【问题标题】:SUM of dynamic Columns in PIVOT table in SQL ServerSQL Server 中 PIVOT 表中动态列的总和
【发布时间】:2015-09-07 12:17:03
【问题描述】:

我有一个动态 PIVOT 查询,其中动态生成列。

我的餐桌:ATTENDANCE_MASTER 包含:ID、Stud_id、ATT_DATE、PRESENT

其中存储的数据如下:

ID  Stud_id ATT_DATE   PRESENT
1     1     2015-08-1    1
2     2     2015-08-1    0
3     3     2015-08-1    1
4     1     2015-08-2    0
5     2     2015-08-2    1
6     3     2015-08-2    1

我创建了 PIVOT 查询

DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX);

SET @columns = N'';
SELECT @columns += N', p.' + QUOTENAME(ATT_DATE)
  FROM (SELECT p.ATT_DATE FROM dbo.ATTENDANCE_MASTER AS p
  GROUP BY p.ATT_DATE) AS x;

SET @sql = N'SELECT Stud_id, ' + STUFF(@columns, 1, 2, '') + '
FROM
(
  SELECT p.ATT_DATE, p.Stud_id, p.PRESENT FROM dbo.ATTENDANCE_MASTER AS p
) AS j
PIVOT
(
  SUM(PRESENT) FOR ATT_DATE IN ('+ STUFF(REPLACE(@columns, ', p.[', ',['), 1, 1, '') + ')
) AS p;';
PRINT @sql;
EXEC sp_executesql @sql;

我需要像这样的列的总和

Stud_ID  2015-08-01   2015-08-2 2015-08-3 Total
1            1            0         1      2
2            1            1         1      3
3            1            1         0      2
4            0            0         1      1

请给我建议解决方案。

提前致谢。

【问题讨论】:

  • 我知道如何计算静态列的总和,但我不知道如何计算动态列的总和
  • 你现在有什么输出?
  • 这里的动态是什么?日期列数?
  • 现在我有上面的输出除了总列
  • 是的,日期的列名是动态@bmsqldev

标签: sql-server pivot powerpivot pivotviewer activepivot


【解决方案1】:

我首先建议不要使用变量连接来创建列列表。 It's behaviour is undefined and can be unexpected。而是使用 SQL Server 的 XML 扩展:

SET @Columns = (SELECT  N', p.' + QUOTENAME(p.Att_Date)
                FROM    dbo.ATTENDANCE_MASTER AS p
                GROUP BY p.ATT_DATE
                ORDER BY p.ATT_DATE
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)');

然后您可以简单地使用@Columns 来创建总计的表达式,因此使用:

', Total = ' + STUFF(REPLACE(@columns, ', p.[', ' + p.['), 1, 3, '')

你会得到类似的东西:

, Total = p.[2015-08-01] + p.[2015-08-02]

您可以将其添加到您的动态 SQL 中,因此对于一个完整的工作示例:

IF OBJECT_ID(N'tempdb..#T', 'U') IS NOT NULL DROP TABLE #T;
CREATE TABLE #T ([ID] int, [Stud_id] int, [ATT_DATE] datetime, [PRESENT] int);

INSERT INTO #T ([ID], [Stud_id], [ATT_DATE], [PRESENT])
VALUES
    (1, 1, '2015-08-01 00:00:00', 1),
    (2, 2, '2015-08-01 00:00:00', 0),
    (3, 3, '2015-08-01 00:00:00', 1),
    (4, 1, '2015-08-02 00:00:00', 0),
    (5, 2, '2015-08-02 00:00:00', 1),
    (6, 3, '2015-08-02 00:00:00', 1);

DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX);             

SET @Columns = (SELECT  N', p.' + QUOTENAME(REPLACE(CONVERT(VARCHAR(10), p.Att_Date, 111), '/', '-'))
                FROM    #T AS p
                GROUP BY p.ATT_DATE
                ORDER BY p.ATT_DATE
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)');

SET @sql = N'SELECT Stud_id, ' + STUFF(@columns, 1, 2, '') + ', Total = ' + STUFF(REPLACE(@columns, ', p.[', ' + p.['), 1, 3, '') + '
FROM
(
  SELECT p.ATT_DATE, p.Stud_id, p.PRESENT FROM #T AS p
) AS j
PIVOT
(
  SUM(PRESENT) FOR ATT_DATE IN ('+ STUFF(REPLACE(@columns, ', p.[', ',['), 1, 1, '') + ')
) AS p;';
PRINT @sql;
EXEC sp_executesql @sql;

【讨论】:

  • 我还有一个查询,如何在其中使用两个聚合函数,例如 Sum 和 Count。
【解决方案2】:

您可以添加GROUP BY WITH CUBE以获取以下总数:

DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX);

SET @columns = N'';
SELECT @columns += N', p.' + QUOTENAME(ATT_DATE)
  FROM (SELECT p.ATT_DATE FROM dbo.ATTENDANCE_MASTER AS p
  GROUP BY p.ATT_DATE) AS x;

SET @sql = N'SELECT Stud_id, ' + STUFF(@columns, 1, 2, '') + '
FROM
(
  SELECT p.ATT_DATE, p.Stud_id, p.PRESENT 
  FROM dbo.ATTENDANCE_MASTER AS p
  GROUP BY p.ATT_DATE, p.Stud_id, p.PRESENT 
  WITH CUBE
) AS j
PIVOT
(
  SUM(PRESENT) FOR ATT_DATE IN ('+ STUFF(REPLACE(@columns, ', p.[', ',['), 1, 1, '') + ')
) AS p;';
PRINT @sql;
EXEC sp_executesql @sql;

【讨论】:

    猜你喜欢
    • 2013-08-07
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2020-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多