我如何拥有多个支点。我希望得到如下所示的结果。
对于每个Grade和每个Gender,我希望将TotalA和Total B值在一行中的4列中对齐。我的最终结果需要包含下面显示的所有10列。
我想要的输出[需要包含2行并保留GENDER列]: 我试过下面的内容:但脚本删除了我的Gender列,无法同时将2列(TotalA,TotalB)转换为4个附加列。
SELECT *,
[TotalA_Male] = [M],
[TotalB_Female] = [F]
FROM
(
SELECT * FROM table) AS s
PIVOT
(
MAX(TotalA) FOR [Gender] IN ([M],[F])
) AS p
答案 0 :(得分:1)
您只能在一个列上进行数据透视,因此您需要将这些TotalA和TotalB列拆分为行,然后根据性别和总数生成一个列并在枢轴中使用它...
select * from (
select
grade,
/* combine the columns for a pivot */
total_gender_details = details + '_' + gender,
totals
from
(values
(1, 'F', cast(7.11321 as float), cast(15.55607 as float)),
(1, 'M', 6.31913, 15.50801),
(2, 'F', 5.26457, 6.94687),
(2, 'M', 6.34666, 9.29783)
) t(grade,gender,totalA,totalB)
/* unpivot the totals into rows */
unpivot (
totals
for details in ([totalA], [totalB])
) up
) t
pivot (
sum(totals)
for total_gender_details in ([totalA_M],[totalA_F],[totalB_M],[totalB_F])
) p
答案 1 :(得分:1)
我认为你根本不想要一个支点。您希望找到总列的部分总和,按一些关键列分组(在这种情况下看起来像Country
和Grade
)。窗口函数允许您执行此部分求和。但是,它们不会按性别进行过滤。您需要在CASE
内使用SUM()
表达式,仅在您的部分金额中包含男性或女性:
SELECT *,
SUM(CASE WHEN Gender = 'M' THEN TotalA ELSE 0 END) OVER(PARTITION BY Country, Grade) AS TotalA_Male,
SUM(CASE WHEN Gender = 'F' THEN TotalA ELSE 0 END) OVER(PARTITION BY Country, Grade) AS TotalA_Female,
SUM(CASE WHEN Gender = 'M' THEN TotalB ELSE 0 END) OVER(PARTITION BY Country, Grade) AS TotalB_Male,
SUM(CASE WHEN Gender = 'F' THEN TotalB ELSE 0 END) OVER(PARTITION BY Country, Grade) AS TotalB_Female
FROM totals
另请参阅:https://msdn.microsoft.com/en-us/library/ms189461.aspx
基本上,窗口函数允许您在GROUP BY
列表中作为单列表达式的一部分执行SELECT
。聚合和分组的结果包含在每一行中,就像它是任何其他表达式一样。请注意查询的其余部分中没有GROUP BY
或PIVOT
。 PARTITION BY
子句中的OVER()
与GROUP BY
类似,指定如何对结果集中的行进行分组以执行指定的聚合(在本例中为SUM()
)。