简体   繁体   中英

Unpivot with varying number of columns

I have been given a table of data that I need to extract and normalize. It looks like this:

AccountName BrandCoke BrandPepsi BrandDiet SalesCoke SalesPepsi SalesDiet
Account1       X          X                  100       200                
Account2                  X          X                 300        400
Account3       X                             500

I need to normalize it, converting columns to rows like so:

AccountName  Brand  Sales
Account1     Coke   100
Account1     Pepsi  200
Account2     Pepsi  300
Account2     Diet   400
Account3     Coke   500

It looks like a good candidate for using UNPIVOT , except I am unsure how to account for the fact that the brand name depends on whether there is an "X" in columns 2-4 and the fact that I only need a row for the brand if there is an "X" in that brand's column. (So only 5 rows should be generated, not 9)

My other thought was to use the SQL2000 way of doing this before UNPIVOT and do separate SELECTS like this:

SELECT AccountName, Brand='Coke', Sales = SalesCoke FROM T WHERE BrandCoke = 'X'
UNION
SELECT AccountName, Brand='Pepsi', Sales = SalesPepsi FROM T WHERE BrandPepsi = 'X'
UNION
SELECT AccountName, Brand='Diet', Sales = SalesDiet FROM T WHERE BrandDiet = 'X'

But that seems rather inelegant.

Can this be done easily with UNPIVOT, or is UNIONing multiple SELECTs a better solution?

Since you are using SQL Server 2008 you should be able to use CROSS APPLY with VALUES to unpivot the columns in pairs. The syntax will be:

select AccountName, Brand, Sales
from yourtable
cross apply
(
  values
    ('Coke', BrandCoke, SalesCoke),
    ('Pepsi', BrandPepsi, SalesPepsi),
    ('Diet', BrandDiet, SalesDiet)
) c (Brand, origCol, Sales)
where origCol is not null;

See SQL Fiddle with Demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM