2

原始问题

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

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
4

2 回答 2

3

你也可以像这样做枢轴:

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声明也是一个非常合理的选择。我倾向于坚持使用显式版本(上图),因为它让我在添加列时更加灵活。

于 2013-03-21T13:38:50.233 回答
2

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

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

SQL 小提琴演示


如果您不想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);

更新的 SQL Fiddle 演示

于 2013-03-21T12:53:53.197 回答