MS-SQL Pivot分两列

时间:2018-09-28 09:29:20

标签: sql-server pivot

我在MS-SQL数据库中获得了以下数据

Manufacturer|Model|Location|Inventory|Sold
------------|-----|--------|---------|-----
Alpha       |One  |USA     |3000     |123
Alpha       |One  |UK      |2300     |53
Beta        |Two  |USA     |1300     |45
Beta        |Two  |UK      |620      |12
Gamma       |Three|USA     |520      |155
Gamma       |Three|UK      |250      |19

我想获得

Manufacturer|Model|Inventory UK|Sold UK|Inventory USA|Sold USA
------------|-----|------------|-------|-------------|--------
Alpha       |One  |2300        |53     |3000         |123
Beta        |Two  |620         |12     |1300         |45
Gamma       |Three|250         |19     |520          |155

如果我理解正确,我应该进行两次旋转,但是目前我仍在如何获得此信息上

SELECT *
FROM Data
PIVOT (max([Inventory]) FOR Location IN ([UK],[USA])) Piv1
PIVOT (max([Sold]) FOR Location IN ([UK],[USA])) Piv2
group by Manufacturer,Model,..?

但是,当然,我仍然远远不能理解应该如何进行。 有人可以帮帮我吗? 非常感谢

3 个答案:

答案 0 :(得分:4)

这是直接使用SQL Server的PIVOT运算符执行此操作的一种方法:

SELECT
    Manufacturer,
    Model,
    MAX(UK) AS [Inventory UK],
    MAX(UK1) AS [Sold UK],
    MAX(USA) AS [Inventory USA],
    MAX(USA1) AS [Sold USA]
FROM
(
    SELECT Manufacturer, Model, Location, Location + '1' AS Location1, Inventory, Sold
    FROM Data
) AS P
PIVOT (MAX([Inventory]) FOR Location IN ([UK],[USA])) Piv1
PIVOT (MAX([Sold]) FOR Location1 IN ([UK1],[USA1])) Piv2
GROUP BY Manufacturer, Model
ORDER BY Manufacturer;

enter image description here

Demo

答案 1 :(得分:1)

您可以使用条件聚合来透视数据:

declare @tmp table(Manufacturer varchar(50), 
                   Model varchar(50), Location varchar(50), Inventory int, Sold int)

insert into @tmp values
 ('Alpha','One'  ,'USA',3000  ,123)
,('Alpha','One'  ,'UK' ,2300  ,53 )
,('Beta ','Two'  ,'USA',1300  ,45 )
,('Beta ','Two'  ,'UK' ,620   ,12 )
,('Gamma','Three','USA',520   ,155)
,('Gamma','Three','UK' ,250   ,19 )

select Manufacturer, Model
,sum (case when Location ='UK' then Inventory else 0 end) as Inventory_UK
,sum (case when Location ='UK' then Sold else 0 end) as Sold_UK
,sum (case when Location ='USA' then Inventory else 0 end) as Inventory_USA
,sum (case when Location ='USA' then Sold else 0 end) as Sold_USA

from @tmp 
group by Manufacturer, Model
order by Manufacturer, Model

结果:

enter image description here

答案 2 :(得分:1)

您可以通过执行动态sql查询来实现。

查询

declare @sql as varchar(max);

select @sql = 'select [Manufacturer], [Model], ' + stuff((
        select distinct ',sum(case [Location] when ' + char(39) + [Location] + char(39) 
        + ' then [Inventory] end) as [Inventory_' + [Location] + ']'
        + ',sum(case [Location] when ' + char(39) + [Location] + char(39) 
        + ' then [Sold] end) as [Sold_' + [Location] + ']'
        from [your_table_name]
        for xml path('')
    )
    , 1, 1, ''
);

select @sql += 'from [your_table_name] group by [Manufacturer], [Model];';

exec(@sql);

Find a demo here