PIVOT Oracle - transform multiple row data to sing

2019-07-22 03:23发布

问题:

I have a need to transfer the following data set:

in which only the highlighted lines are the one of interest (Tag in ('LN','SN')) as I am only interested in SerialNumber and LotNumber of the products. I would like to convert the data set above into the following data set:

Where it lists the product along with its serialnumber and lot number in 1 row.

After doing some reading online, I think PIVOT might be what I need. However, I am struggling with the technical side of the statement.

I have tried:

select * from (
select * from TEST2 where tag in ('LN','SN')
)
PIVOT
(
  max(value)
  for tag in ('LN','SN')
)
order by category,subcat,item,"Date"

but this does not generate the output I wanted. Any suggestion? Is PIVOT the correct statement to use or is there some other statement that is more appropriate in this case? I realize that PIVOT requires an aggregate function but I do not count or add anything. Please advise.

Below is my test table with its data

  CREATE TABLE "TEST2" 
   (    "Date" DATE, 
    "SUBCAT" VARCHAR2(6 BYTE), 
    "CATEGORY" VARCHAR2(7 BYTE), 
    "VALUE" VARCHAR2(17 BYTE), 
    "ITEM" VARCHAR2(2 BYTE), 
    "DESCRIPTION" VARCHAR2(15 BYTE), 
    "TAG" VARCHAR2(3 BYTE)
   ) 


Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('24-OCT-13','DD-MON-RR'),'290223','1219576',null,'25','OTHER ATTRIBUTE','OA');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('24-OCT-13','DD-MON-RR'),'290223','1219576',null,'25','SOME COMMENTS','SC');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('24-OCT-13','DD-MON-RR'),'290223','1219576','1105618','25','Lot Number','LN');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('24-OCT-13','DD-MON-RR'),'290223','1219576','12','25','NOT RELEVANT','NR');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('24-OCT-13','DD-MON-RR'),'290223','1219576','45','25','NOT USE','NU');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('24-OCT-13','DD-MON-RR'),'290223','1219576','-1','25','DO NOT CARE','DC');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('24-OCT-13','DD-MON-RR'),'290223','1219576','3x12mm','25','Serial Number','SN');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('24-OCT-13','DD-MON-RR'),'290223','1219576',null,'25','ABC','ABC');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('24-OCT-13','DD-MON-RR'),'290223','1219576',null,'25','Whatever','DEF');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('24-OCT-13','DD-MON-RR'),'290223','1219576',null,'28','SOME ATTRIBUTE','SA');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('24-OCT-13','DD-MON-RR'),'290223','1219576',null,'28','OTHER ATTRIBUTE','OA');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('24-OCT-13','DD-MON-RR'),'290223','1219576','isq: 75, 80','28','Other Comments','OC');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('24-OCT-13','DD-MON-RR'),'290223','1219576',null,'28','SOME COMMENTS','SC');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('24-OCT-13','DD-MON-RR'),'290223','1219576','1303757','28','Lot Number','LN');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('24-OCT-13','DD-MON-RR'),'290223','1219576','12','28','NOT RELEVANT','NR');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('24-OCT-13','DD-MON-RR'),'290223','1219576','40','28','NOT USE','NU');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('24-OCT-13','DD-MON-RR'),'290223','1219576','0','28','DO NOT CARE','DC');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('24-OCT-13','DD-MON-RR'),'290223','1219576',null,'28','ABC','ABC');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('24-OCT-13','DD-MON-RR'),'290223','1219576',null,'28','Whatever','DEF');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('18-JUN-15','DD-MON-RR'),'354506','1219576',null,'4','SOME ATTRIBUTE','SA');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('18-JUN-15','DD-MON-RR'),'354506','1219576',null,'4','OTHER ATTRIBUTE','OA');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('18-JUN-15','DD-MON-RR'),'354506','1219576','1403114','4','Lot Number','LN');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('18-JUN-15','DD-MON-RR'),'354506','1219576','11','4','NOT RELEVANT','NR');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('18-JUN-15','DD-MON-RR'),'354506','1219576','50','4','NOT USE','NU');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('18-JUN-15','DD-MON-RR'),'354506','1219576','0','4','DO NOT CARE','DC');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('18-JUN-15','DD-MON-RR'),'354506','1219576',null,'4','Whatever','DEF');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('18-JUN-15','DD-MON-RR'),'354506','1219576','7777777777','9','Lot Number','LN');
Insert into TEST2 ("Date",SUBCAT,CATEGORY,VALUE,ITEM,DESCRIPTION,TAG) values (to_date('18-JUN-15','DD-MON-RR'),'354506','1219576','9.999999999999E12','9','Serial Number','SN');

回答1:

You aren't doing anything with the description, which also varies with the tag. It isn't aggregated so it in the implicit 'group by', so you get separate rows in the result set.

You can either capture that too with another (dummy) aggregate:

select * from (
  select * from TEST2 where tag in ('LN', 'SN')
)
PIVOT
(
  max(value) as value, max(description) as description
  for tag in ('LN' as ln, 'SN' as sn)
)
order by category, subcat, item, "Date";

Date      SUBCAT CATEGOR IT LN_VALUE          LN_DESCRIPTION  SN_VALUE          SN_DESCRIPTION
--------- ------ ------- -- ----------------- --------------- ----------------- ---------------
24-OCT-13 290223 1219576 25 1105618           Lot Number      3x12mm            Serial Number  
24-OCT-13 290223 1219576 28 1303757           Lot Number                                       
18-JUN-15 354506 1219576 4  1403114           Lot Number                                       
18-JUN-15 354506 1219576 9  7777777777        Lot Number      9.999999999999E12 Serial Number  

Or more likely exclude it from the intermediate result set if you don't want it, by specify the columns you do want instead of using *:

select * from (
  select category, subcat, item, "Date", tag, value
  from TEST2 where tag in ('LN', 'SN')
)
PIVOT
(
  max(value) for tag in ('LN' as ln, 'SN' as sn)
)
order by category, subcat, item, "Date";

CATEGOR SUBCAT IT Date      LN                SN              
------- ------ -- --------- ----------------- -----------------
1219576 290223 25 24-OCT-13 1105618           3x12mm           
1219576 290223 28 24-OCT-13 1303757                            
1219576 354506 4  18-JUN-15 1403114                            
1219576 354506 9  18-JUN-15 7777777777        9.999999999999E12