I have some legacy product data that has proven difficult to work with. The products can be sold with 1, 2 or 3 parts, and the way the system was designed, parts 2 and 3 for an ordered product were simply subsequent rows after the first row for that product.
Here is some sample data....
----------------------------------------------------------
OrderId Sku Type Row_Id OtherColumns...
----------------------------------------------------------
123 001 Double 0 Other stuff..
123 001 Double 1 Other stuff..
123 001 Double 2 Other stuff..
123 001 Double 3 Other stuff..
123 002 Single 4 Other stuff..
123 003 Triple 5 Other stuff..
123 003 Triple 6 Other stuff..
123 003 Triple 7 Other stuff..
123 001 Double 8 Other stuff..
123 001 Double 9 Other stuff..
123 002 Single 10 Other stuff..
123 002 Single 11 Other stuff..
123 002 Single 12 Other stuff..
123 002 Single 13 Other stuff..
The old software (VB) deals with this by iterating over the rows and looking forward as it loops, getting the information it needs from the rows, and then skips them.
Fast forward 8 years...I have inherited this system in my new job and have rewritten the system from the ground up. The problem I'm having is getting that legacy data into my new format.
I'm looking for a way to select the same data, and partition it by the appropriate segment numbers. I've used RANK() OVER(PARTITION BY) with no success. I think I'm just not doing it right.
Ideally, I'd like to be able to generate a result set that looks like this: (NOTE the Segment column)
-------------------------------------------------------------------
OrderId Sku Type Row_Id Segment OtherColumns...
-------------------------------------------------------------------
123 001 Double 0 1 Other stuff..
123 001 Double 1 2 Other stuff..
123 001 Double 2 1 Other stuff..
123 001 Double 3 2 Other stuff..
123 002 Single 4 1 Other stuff..
123 003 Triple 5 1 Other stuff..
123 003 Triple 6 2 Other stuff..
123 003 Triple 7 3 Other stuff..
123 001 Double 8 1 Other stuff..
123 001 Double 9 2 Other stuff..
123 002 Single 10 1 Other stuff..
123 002 Single 11 1 Other stuff..
123 002 Single 12 1 Other stuff..
123 002 Single 13 1 Other stuff..
Ideally, I'd like to avoid cursors or loops. I'll be using the query to migrate millions of records that are derived from multiple tables.
Thanks in advance for your help.
EDIT
I've updated the sample data to show that I do indeed have back to back groups that I need to isolate.
select OrderId,
Sku,
Type,
Row_Id,
(row_number() over(partition by Type order by Row_Id) - 1) %
case Type
when 'Single' then 1
when 'Double' then 2
when 'Triple' then 3
end + 1
from YourTable
order by Row_Id
SQL Fiddle
Related
I have a data structure issue. I have a problem where I need to roll up my data within tableau so that aggregated numbers do not skew in a certain manner.
Example of current data
ID Model_Number Value
123 fff 2
123 ggg 2
123 hhh 2
123 uuu 2
124 yyy 5
124 qqq 5
124 eee 5
Avg: NA 3.28
Ideal state of data and aggregation
ID Value
123 2
124 5
Avg 3.5
As you see since the data is at two different grains the aggregated number (avg) will be different. I would like to roll up my numbers to the distinct value of ID and then calculate my average which will result in a different (correct in my context) aggergated number.
Here is one calculated field that could help.
{ FIXED [ID] : AVG([Value]) }
This will give you the avg value by ID. You can then use a grand total(avg) to get the 3.5
I have four Postgres tables:
Professions
id
name
123
profession 1
345
profession 2
Versions
id
professionId
status
createdAt
567
123
Live
2020-01-01
999
123
Draft
2021-02-01
666
345
Live
2021-01-01
Organisations
id
name
333
organisation 1
444
organisation 2
655
organisation 3
ProfessionToOrganisation
id
professionId
organisationId
Role
665
123
333
Regulator
533
123
444
Something else
534
345
444
Regulator
I am trying to get the latest version of each profession, regardless of their status, so am using a combination of DISTINCT ON and ORDER BY like so:
SELECT DISTINCT ON (
professionVersions.professionId,
professions.name
) professionVersions.id AS "professionVersions_id", professions.name, organisations.name
FROM professionVersions
LEFT JOIN professions ON professions.id = professionVersions.professionId
LEFT JOIN professionToOrganisation ON
professionToOrganisation.professionId = professions.id
LEFT JOIN organisations ON professionToOrganisation.organisationId = organisations.id
ORDER BY
professions.name,
professionVersions.professionId,
professionVersions.created_at DESC
However, I only get one organisation returned for each profession, i.e:
professionVersions_id
name
name
999
Profession 1
Organisation 1
666
Profession 2
Organisation 2
Whereas I wouild like:
professionVersions_id
name
name
999
Profession 1
Organisation 1
999
Profession 1
Organisation 2
666
Profession 2
Organisation 2
How do I go about achieving this?
I've got a DB Fiddle here - https://www.db-fiddle.com/f/44iWbw7oyDtVMsQfE45jPA/0
I need to concatenate the rows(taille). for example, for the code_commande 001 and code_article=1, I need to concatenate in list all taille which have these two conditions. another example, for code_commande=001 and code_article=2, the same job I need to concatenate in a list all taille which have these two conditions. this for all
code_commande code_article taille
001 1 s
001 1 m
001 1 xl
001 1 x52
001 2 m
001 1 5566
001 2 x52
001 1 xl
002 1 s
002 2 m
001 3 xxl
002 3 xs
001 1 ml
001 1 xs32
I need to concatenate taille for each code_commande for each code_article
example of result:
001 1 s,m,xl etcc
dynamically
I should have a table who grouped the ( taille) for each code_commande for each code_article like:
001 1 s,m,xl,
001 2 s,xl,l
002 1 xs,ettcc
I have tried this query but ,it concatenate all (taille) for all rows
the query
Select [code_commande],[code_article], SUBSTRING(
(
SELECT ',' +[taille] AS 'data()'
FROM [dbo].[commande] FOR XML PATH('')
), 2 , 9999) As taille_commande
from [dbo].[commande]
order by [code_article],[code_commande]desc
As mentioned, STRING_AGG() is your friend for this requirement. Assuming your original post contained the schema you're working with, a simple aggregate query will give you the results you want.
select code_commande, code_article, STRING_AGG(taille, ',') as taille_commande
from dbo.commande
group by code_commande, code_article
STRING_AGG reference
Note this is only available in SQL Server 2017+ and azure. To see a possible solution for previous versions, see this duplicate.
I have two tables:
table1 =tbl_main:
item_id fastec_qty
001 102
002 200
003 300
004 400
table2= tbl_dOrder
order_id item_id amount
1001 001 30
1001 002 40
1002 001 50
1002 003 70
How can I write a query so that the result of the tables are as follows:
item_id amount difference
001 102 22
002 200 160
003 300 230
004 400 400
The difference between the amount in table 1 and the total amounts disbursed from the Table 2.
SELECT q.item_id, a.fastec_qty AS amount, a.fastec_qty - q.amount AS difference
FROM (
SELECT item_id, SUM(amount) AS amount
FROM tbl_dOrder
GROUP BY item_id
) q
JOIN tbl_main a ON a.item_id = q.item_id
Here this query is going to first SUM the amounts from tbl2 grouped by the item_id, then it's going to JOIN the results of that query with the first table so it can do the calculation for the difference column.
Using Crystal Report 7
ID Name
001 Raja
002 Vijay
003 Suresh
004 Mahes
005 Salma
I want to arrange by id (003, 001, 004, 002, 005)
Expected output
ID Name
003 Suresh
001 Raja
004 Mahes
002 Vijay
005 Salma
Note: Maximum row is 5 only, it will not exceed more than 5.
I need to add 5 group or any other method is there for arranging the rows.
Need Crystal report formula or suggestion help
In later versions of crystal you can set a custom sort order but if this feature isn't available in CR7 you should be able to create a formula:
if {table.id} = '003' then
1
else if {table.id} = '001' then
2
else if {table.id} = '004' then
3
else if {table.id} = '002' then
4
else if {table.id} = '005' then
5
else
999;
Then sort on that formula.