Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
300 views
in Technique[技术] by (71.8m points)

sql - Multiple rows values into a single row

I have a requirement in oracle SQL where the multiple rows are to be converted into single row.

Here is the example :

Empid Ele_name Inp_name Inp_Value   EntryId     Start_date      End Date
123     LW      MA      1637    100000104856397     06-Nov-17       31-Dec-12
123     LW      CA      Y       100000104856397     06-Nov-17       31-Dec-12
143     LW      MA      1637    100000104856504     06-Nov-17       31-Dec-12
143     LW      CA      Y       100000104856504     06-Nov-17       31-Dec-12
144     MTS     AA      1000    300002685277016     12-Dec-17       31-Dec-12
144     MTS     CA      Y       300002685277016     12-Dec-17       31-Dec-12
144     LW      CA      Y       300002685277012     06-Nov-17       31-Dec-12
144     LW      AA      200     300002685277012     06-Nov-17       31-Dec-12

The expected output is

Empid   Element_name    FIrstName  LastName  Initials  Input_name1  Input_Value1    Input_name2  Input_Value2  Input_name3    Input_Value3     Input_name4    Input_Value4    Input_name5      Input_Value5       EntryId                Start_date     End Date
123       LW             null       null       null      MA            1637            CA              Y           null          null             null           null            null            null           100000104856397        06-Nov-17    31-Dec-12
143       LW             null       null       null      MA            1637            CA              Y           null          null             null           null            null            null           100000104856504        06-Nov-17     31-Dec-12
144       MTS             null       null       null      AA            1000            CA              Y           null          null             null           null            null            null           300002685277016        12-Dec-17    31-Dec-12
144       LW             null       null       null      CA            Y                AA            200           null          null             null           null            null            null           300002685277012        06-Nov-17    31-Dec-12

I heard that this can be done with Pivot. But i am new to the concept. Can anyone help here.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You need to do some more work before you can pivot like that, because pivoting takes row data and makes it into column names, but none of your row data is 1, 2, 3, 4... to use as a column name (inp_value1 <-- the 1 here)

You can do this, which is probably easier to understand:

SELECT
  Empid,
  Ele_name,
  MAX(CASE WHEN rown = 1 THEN Inp_name END) as Inp_name1,
  MAX(CASE WHEN rown = 1 THEN Inp_value END) as Inp_Value1,
  MAX(CASE WHEN rown = 2 THEN Inp_name END) as Inp_name2,
  MAX(CASE WHEN rown = 2 THEN Inp_value END) as Inp_Value2,
  MAX(CASE WHEN rown = 3 THEN Inp_name END) as Inp_name3,
  MAX(CASE WHEN rown = 3 THEN Inp_value END) as Inp_Value3,
  MAX(CASE WHEN rown = 4 THEN Inp_name END) as Inp_name4,
  MAX(CASE WHEN rown = 4 THEN Inp_value END) as Inp_Value4,
  MAX(CASE WHEN rown = 5 THEN Inp_name END) as Inp_name5,
  MAX(CASE WHEN rown = 5 THEN Inp_value END) as Inp_Value5,
  MAX(CASE WHEN rown = 6 THEN Inp_name END) as Inp_name6,
  MAX(CASE WHEN rown = 6 THEN Inp_value END) as Inp_Value6,
  EntryId,     
  Start_date,      
  End_Date
FROM
  (SELECT t2.*, ROW_NUMBER() OVER(PARTITION BY EmpId, Ele_name ORDER BY 1) as rown FROM t2) d
GROUP BY 
  Empid,
  Ele_name, 
  EntryId,     
  Start_date,      
  End_Date
  • ps; why specify name3/4/5/6 in your expected output if they're all null? If the data will never have more than 2 rows per empid/ele_name pair then you can just write null as input_name3.. and so on
  • pps: i called my table t2 - edit your name into the query
  • ppps; I don't know if the column "end date" really has a space in the name, I called mine with an underscore

Or you can pivot like this (harder to understand but more compact):

SELECT
  Empid,
  Ele_name,
  pvt.*,
  EntryId,     
  Start_date,      
  End_Date
FROM
  (SELECT t2.*, ROW_NUMBER() OVER(PARTITION BY EmpId, Ele_name ORDER BY 1) as rown
   FROM t2) d
PIVOT( 
  MAX(inp_name) as inp_name, 
  MAX(inp_value) as inp_value 
  FOR rown in (1,2,3,4,5,6) 
) pvt

but the columns will come out of the pvt.* with names as 1_inp_name, 1_inp_value .. You'll have to use AS to rename them


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...