How to pivot row data into specific columns db2 - sql

I would like to pivot results from a table into a new structure. So that it can map all the children to the parent product.
Current Result
Parent_Prod_Num|Child_Prod_Num|Child_Prod_Code|Child_Prod_Name
1|11|a123|a
1|12|b123|ab
1|13|c123|abc
Expected Result
Parent_Prod_Num|Child_Prod_Num_1| Child_Prod_Code_1|Child_Prod_Name_1| Child_Prod_Num_2| Child_Prod_Code_2|Child_Prod_Name_2| Child_Prod_Num_3| Child_Prod_Code_3|Child_Prod_Name_3
1|11|a123|a|12|b123|ab|13|c123|abc

For a fixed maximum number of children per parent, you can enumerate the rows with row_number(), then pivot with conditional aggregation:
select parent_prod_num,
max(case when rn = 1 then child_prod_num end) as child_prod_num_1,
max(case when rn = 1 then child_prod_code end) as child_prod_code_1,
max(case when rn = 1 then child_prod_name end) as child_prod_name_1,
max(case when rn = 2 then child_prod_num end) as child_prod_num_2,
max(case when rn = 2 then child_prod_code end) as child_prod_code_2,
max(case when rn = 2 then child_prod_name end) as child_prod_name_2,
max(case when rn = 3 then child_prod_num end) as child_prod_num_3,
max(case when rn = 3 then child_prod_code end) as child_prod_code_3,
max(case when rn = 3 then child_prod_name end) as child_prod_name_3
from (
select t.*, row_number() over(partition by parent_prod_num order by child_prod_num) rn
from mytable t
) t
group by parent_prod_num

Related

Combine multiple rows to single row group by Specific column

I have a table that looks similar to this here:
I would like to able to combine all that data when they have the same Id.
Which would look like this:
Use conditional aggregation:
select id,
max(case when seqnum = 1 then section end) as section1,
max(case when seqnum = 1 then value1 end) as section1_value1,
max(case when seqnum = 1 then value2 end) as section1_value2,
max(case when seqnum = 2 then section end) as section2,
max(case when seqnum = 2 then value1 end) as section2_value1,
max(case when seqnum = 2 then value2 end) as section2_value2
from (select t.*,
row_number() over (partition by id order by section) as seqnum
from t
) t
group by id;

Grouping multiple lines onto one in Oracle SQL

How can I get this data set in Image 1 to look like the data in Image 2. Basically rather than having each purchase on its own line I want to group by Name and have all that persons purchases on one line. They can buy a max of 5 items and my database is about 30 million lines worth of purchases.
P.S The date order is not important
You can use row_number() and conditional aggregation:
select name,
max(case when seqnum = 1 then item end) as item_1,
max(case when seqnum = 1 then date end) as date_1,
max(case when seqnum = 2 then item end) as item_2,
max(case when seqnum = 2 then date end) as date_2,
max(case when seqnum = 3 then item end) as item_3,
max(case when seqnum = 3 then date end) as date_3
from (select t.*,
row_number() over (partition by name order by date asc) as seqnum
from t
) t
group by name;
You can use PIVOT with row_number as follows:
Select * from
(select t.*,
row_number() over (partition by name order by date_purchased) rn
from your_table t
) PIVOT
(Max(item_purchased), max(date_purchased) For rn in (1,2,3));

Converting three Rows to one row

I'm trying to convert Rows to Columns from a MS SQL table...
my MS SQL table is like...
I want to SELECT the output as below...
I tried with pivot tables and cross join.. unfortunately could not make it.
any help is highly appreciated
You can use ROW_NUMBER() in a subquery to rank records, and the do conditional aggregation in the outer query:
SELECT
id,
SubId,
MAX(CASE WHEN rn = 1 THEN code END) Code1,
MAX(CASE WHEN rn = 1 THEN TotalAmount END) Code1TotalAmount,
MAX(CASE WHEN rn = 1 THEN TotalDays END) Code1TotalDays,
MAX(CASE WHEN rn = 2 THEN code END) Code2,
MAX(CASE WHEN rn = 2 THEN TotalAmount END) Code2TotalAmount,
MAX(CASE WHEN rn = 2 THEN TotalDays END) Code2TotalDays,
MAX(CASE WHEN rn = 3 THEN code END) Code3,
MAX(CASE WHEN rn = 3 THEN TotalAmount END) Code3TotalAmount,
MAX(CASE WHEN rn = 3 THEN TotalDays END) Code3TotalDays
FROM (
SELECT
t.*,
ROW_NUMBER() OVER(PARTITION BY ID, SubId ORDER BY code) rn
FROM mytable t
) x
GROUP BY ID, SubId

SQL PIVOT table with MIN() and on Multiple columns

Here is the table structure
ID TypeX TypeXDesc XDate TypeCodeY
040001 3669 Unspecified Cat 2005-08-08 1
040001 3669 Unspecified Cat 2006-08-29 2
040001 37515 Tear Film 2005-08-08 1
040001 37999 Disor 2004-07-22 1
Transform above table INTO below USING PIVOT
ID TypeX_1 TypeXDesc_1 XDate_1 TypeCodeY_1 TypeX_2 TypeXDesc_2 XDate_2 TypeCodeY_2 TypeX_3 TypeXDesc_3 XDate_3 TypeCodeY_3
040001 3669 Unspecified Cat 2005-08-08 1 37515 Tear Film 2005-08-08 1 37999 Disor 2004-07-22 1
Look at the same TypeX code but XDate is different and we need to get Min(XDate) so first row is qualified not the second row.
You can accomplish this using conditional aggregation. In this case, you can enumerate the rows with within typex/id groups using row_number(). You can enumerate the groups with with typex/id using dense_rank().
Then, use conditional aggregation:
select t.id,
max(case when grpnum = 1 and seqnum = 1 then typex end) as typex_1,
max(case when grpnum = 1 and seqnum = 1 then TypeXDesc end) as TypeXDesc_1,
max(case when grpnum = 1 and seqnum = 1 then XDate end) as XDate_1,
max(case when grpnum = 1 and seqnum = 1 then TypeCodeY end) as TypeCodeY_1,
max(case when grpnum = 2 and seqnum = 1 then typex end) as typex_12,
max(case when grpnum = 2 and seqnum = 1 then TypeXDesc end) as TypeXDesc_2,
max(case when grpnum = 2 and seqnum = 1 then XDate end) as XDate_2,
max(case when grpnum = 2 and seqnum = 1 then TypeCodeY end) as TypeCodeY_3,
max(case when grpnum = 3 and seqnum = 1 then typex end) as typex_1,
max(case when grpnum = 3 and seqnum = 1 then TypeXDesc end) as TypeXDesc_3,
max(case when grpnum = 3 and seqnum = 1 then XDate end) as XDate_3,
max(case when grpnum = 3 and seqnum = 1 then TypeCodeY end) as TypeCodeY_3
from (select t.*,
row_number() over (partition by id, typex order by xdate as seqnum,
dense_rank() over (partition by id order by typex) as grpnum
from t
) t
group by id;

How to make multiple rows into columns

I've tried MAX CASE WHEN and CTE but for some reason can't exactly figure this out.
My data looks like this:
SELECT RC, isMHy, eligible
FROM test
RC isMHY eligible
190B05 0 1
190K00 1 0
There can be up to 4 rows in the table, I want to the results to look like this (12 columns in case there are 4 rows)
RC1 isMHY1 eligible1 RC2 isMHY2 eligible2
190B05 0 1 190K00 1 0
Any suggestions would be appreciated
You can use conditional aggregation with ROW_NUMBER() :
SELECT MAX(CASE WHEN s.rnk = 1 THEN s.rc END) as rc1,
MAX(CASE WHEN s.rnk = 1 THEN s.ismhy END) as ismhy1,
MAX(CASE WHEN s.rnk = 1 THEN s.eligible END) as eligible1,
MAX(CASE WHEN s.rnk = 2 THEN s.rc END) as rc2,
MAX(CASE WHEN s.rnk = 2 THEN s.ismhy END) as ismhy2,
MAX(CASE WHEN s.rnk = 2 THEN s.eligible END) as eligible2,
..........
FROM(
SELECT t.*,
ROW_NUMBER() OVER(ORDER BY SELECT 1) as rnk
FROM test t) s