【问题标题】:Group and sum row data into columns in MS-SQL?将行数据分组和汇总到 MS-SQL 中的列中?
【发布时间】:2013-03-10 23:51:28
【问题描述】:

Original Question

我不知道我是应该打开一个新问题还是取消标记最后一个问题! 所以,我想做的是:

WorkWeek  Catg  Item    Cost
WorkWeek1 Cat1  Item1   Price
WorkWeek1 Cat1  Item2   Price
WorkWeek1 Cat2  Item3   Price
WorkWeek1 Cat3  Item4   Price
WorkWeek1 Cat3  Item1   Price
WorkWeek2 Cat1  Item1   Price
WorkWeek2 Cat2  Item2   Price
WorkWeek3 Cat1  Item1   Price
WorkWeek4 Cat1  Item2   Price
.
.
WorkWeekA CatB  ItemC   Price

我想创建一个新表,列出每个工作周,然后列出该工作周内每个 catg 的总价格。这就是我现在的做法,但查询只是将每个 ww 的所有内容相加,给我所有工作周的相同总和:

select
    workweek
    ,(select sum(cost) from DataTable where Catg = 'Cat1') as Cat1TotalCost
    ,(select sum(cost) from DataTable where Catg = 'Cat2') as Cat2TotalCost
    ,(select sum(cost) from DataTable where Catg = 'Cat3') as Cat3TotalCost
    .
    .
    .
    .
from DataTable
group by Workweek

【问题讨论】:

    标签: sql sql-server-2008 append pivot


    【解决方案1】:

    你也可以这样做:

    select workweek,
           sum(case when Catg = 'Cat1' then cost end) as Cat1TotalCost,
           sum(case when Catg = 'Cat2' then cost end) as Cat2TotalCost,
           sum(case when Catg = 'Cat3' then cost end) as Cat3TotalCost
    from DataTable
    group by Workweek
    

    您不应该为每个值执行单独的子查询。

    pivot 语句也是一个非常合理的替代方案。我倾向于坚持使用显式版本(上图),因为它让我在添加列时更加灵活。

    【讨论】:

    • 我正在尝试实现这个解决方案。我四处搜索,现在知道这称为交叉表查询方法。谢谢。
    • 我正在 Access 中尝试此操作,但遇到愚蠢的语法错误。环顾四周,但找不到为什么无法访问运行此 sql 代码: select ww ,sum(case when f.gl_num='532100' then valuecocur end) as Chem from fadsfd f
    • @camelbrush 。 . .在访问中,您必须使用iif 而不是case
    • 我所做的是使用 SSMA 将 db 放入 ms sql 然后使用您的示例编写我的查询。它对我有用。 :) 非常感谢。有什么理由,我应该开始学习 sql 中的 PIVOT 选项吗?
    • @UriAbramson 。 . .如果没有匹配项,原始查询将返回 NULL。可以轻松更改此版本以将else 0 添加到每个条件。不需要额外的函数调用。
    【解决方案2】:

    您可以使用PIVOT 表运算符来代替:

    SELECT *
    FROM
    (
      SELECT workweek, catg, cost
      FROM datatable
    ) AS t
    PIVOT
    (
      SUM(cost)
      FOR catg IN (Cat1, Cat2, Cat3)
    ) AS p;
    

    SQL Fiddle Demo


    如果您不想手动列出catg 值,并且希望对表中catg 的所有值动态执行此操作,则可以使用动态SQL 动态执行此操作。比如:

    DECLARE @cols AS NVARCHAR(MAX);
    DECLARE @query AS NVARCHAR(MAX);
    
    select @cols = STUFF((SELECT distinct ',' +
                            QUOTENAME(catg)
                          FROM datatable                      
                          FOR XML PATH(''), TYPE
                         ).value('.', 'NVARCHAR(MAX)') 
                            , 1, 1, '');
    
    SELECT @query = 
        'SELECT 
          *
        FROM 
        (
          SELECT workweek, catg, cost
          FROM datatable
        ) AS t
        PIVOT
        (
          SUM(cost)
          FOR catg IN ( ' + @cols + ')
        ) AS p';
    
    
    
    EXECUTE( @query);
    

    Updated SQL Fiddle Demo

    【讨论】:

    • 这个可以在access中运行吗?
    猜你喜欢
    • 2020-11-17
    • 2014-10-05
    • 2015-03-02
    • 1970-01-01
    • 2018-10-03
    • 2014-11-22
    • 2020-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多