不同数量的列无法旋转

时间:2014-05-08 17:30:22

标签: sql sql-server-2008

我收到了一份需要提取和规范化的数据表。它看起来像这样:

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

我需要对其进行规范化,将列转换为如下所示的行:

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

它似乎是使用UNPIVOT的合适人选,但我不确定如何说明品牌名称取决于是否有" X"在第2-4栏中,如果有一个" X"在该品牌的专栏中。 (因此只应生成5行,而不是9行)

我的另一个想法是在UNPIVOT之前使用SQL2000方式执行此操作,并将SELECTS分开:

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'

但这似乎相当不优雅。

这可以通过UNPIVOT轻松完成,还是UNIONing多个SELECT更好的解决方案?

1 个答案:

答案 0 :(得分:1)

由于您使用的是SQL Server 2008,因此您应该可以使用CROSS APPLY和VALUES来成对地取消对列的拆分。语法为:

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;

请参阅SQL Fiddle with Demo

相关问题