转向同性别

时间:2015-07-09 16:22:19

标签: sql

我如何拥有多个支点。我希望得到如下所示的结果。enter image description here
对于每个Grade和每个Gender,我希望将TotalA和Total B值在一行中的4列中对齐。我的最终结果需要包含下面显示的所有10列。

我想要的输出[需要包含2行并保留GENDER列]: enter image description here 我试过下面的内容:但脚本删除了我的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

2 个答案:

答案 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)

我认为你根本不想要一个支点。您希望找到总列的部分总和,按一些关键列分组(在这种情况下看起来像CountryGrade)。窗口函数允许您执行此部分求和。但是,它们不会按性别进行过滤。您需要在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 BYPIVOTPARTITION BY子句中的OVER()GROUP BY类似,指定如何对结果集中的行进行分组以执行指定的聚合(在本例中为SUM() )。