【问题标题】:How to write a dynamic columns PIVOT query with multiple records?如何编写具有多条记录的动态列 PIVOT 查询?
【发布时间】:2019-06-29 01:20:12
【问题描述】:

EDIT2:我做了一个新的可用示例,进入下一步,但仍然不知道如何做一些事情。请检查。

我有下表:

CREATE TABLE [dbo].[MyTable] (
             [ID] [int] IDENTITY(1,1) NOT NULL
            ,[Name] [nvarchar](50) NULL
            ,[Quantity] [int] NULL
            ,[Period] [nvarchar](10) NULL
            )

INSERT [dbo].[MyTable] VALUES
      ('foo', 1, 'Jan'),
      ('bar', 2, 'Jan'),
      ('foo', 1, 'Jan'),
      ('kin', 1, 'Jan'),
      ('blat', 5, 'Jan'),
      ('foo', 3, 'Feb'),
      ('bar', 1, 'Feb'),
      ('kin', 2, 'Feb'),
      ('blat',4, 'Feb'),
      ('foo', 1, 'Feb'),
      ('kin', 7, 'Feb'),
      ('blat', 1, 'Feb'),
      ('foo', 3, 'Mar'),
      ('bar', 1, 'Mar'),
      ('kin', 1, 'Mar'),
      ('blat', 1, 'Mar'),
      ('bar', 1, 'Mar'),
      ('kin', 2, 'Mar'),
      ('blat', 3, 'Mar')

我想通过在查询中使用 PIVOT 来实现图片中的结果:

到目前为止我的查询:

DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX);
SET @columns = N'';
SELECT @columns += N', p.' + QUOTENAME(Period)
  FROM (SELECT Period FROM dbo.MyTable AS p
  GROUP BY Period) AS x;
SET @sql = N'
SELECT ' + STUFF(@columns, 1, 2, '') + '
FROM
(
  SELECT Name, Period, Quantity
   FROM dbo.MyTable AS p
) AS j
PIVOT
(
  SUM(Quantity) FOR Period IN ('
  + STUFF(REPLACE(@columns, ', p.[', ',['), 1, 1, '')
  + ')
) AS p;';
EXEC sp_executesql @sql;

给我下面的结果:

如何添加行名(foo、bar、kin、blat)、列名 Name、SUM 等?

EDIT3:如何对列和记录进行“排序”?

【问题讨论】:

  • 这里的一些实际样本数据和预期结果会有所帮助。
  • 为什么要写查询?如果你想在 excel 中使用它,请使用数据透视表。这是最简单的解决方案。事实上我很困惑 - 你已经在你的例子中使用了一个数据透视表
  • 样本数据在图片中,预期结果在第一个。因为它是整个过程的一部分,需要通过 SQL 实现自动化。请把 excel 中的结果与 SQL 中的结果进行比较。
  • 那张图片不是样本数据,这是预期的结果;和图片对消耗性数据没有帮助。
  • 我明白了,但你为什么需要样本数据。我的目标是像在 Excel 中一样在查询中添加 PartName 行,而不是我有 PartName 行的 SUM。

标签: sql-server excel tsql pivot pivot-table


【解决方案1】:

托莫,早安,

现在我们有了创建表和插入数据的查询,它可以简单快速地帮助您:-)

请检查以下解决方案是否符合您的需求

select [Name],[Jan],[Feb],[Mar],[Jan]+[Feb]+[Mar] AS Grand_Total
from (
    SELECT [Name], [Quantity],[Period]
    FROM [MyTable]
) src
pivot
(
  SUM(Quantity)
  for Period in ([Jan],[Feb],[Mar])
) piv
GO

下一步是将其转换为动态 PIVOT,一旦我们有了静态解决方案,如果您需要动态 PIVOT,这非常简单。但首先确认静态 PIVOT 返回您需要的内容并且您确实需要动态解决方案(也许这满足您的需求)

更新:使用 ROLLUP 在底部添加“总计”

;With MyCTE as(
select [Name],[Jan],[Feb],[Mar],[Jan]+[Feb]+[Mar] AS Grand_Total
from (
    SELECT [Name], [Quantity],[Period]
    FROM [MyTable]
) src
pivot
(
  SUM(Quantity)
  for Period in ([Jan],[Feb],[Mar])
) piv
)
select ISNULL([Name],'Totoal') as Name ,SUM([Jan]) [Jan],SUM([Feb]) [Feb],SUM([Mar]) [Mar],SUM([Grand_Total]) [Grand_Total]
from MyCTE
GROUP BY ROLLUP ([Name])
GO

按照 OP 的要求添加 Dynamic Pivot 版本

DECLARE 
    @ColumnsList1 AS NVARCHAR(MAX),
    @ColumnsList2 AS NVARCHAR(MAX),
    @ColumnsList3 AS NVARCHAR(MAX),
    @query AS NVARCHAR(MAX);

SET @ColumnsList1 = STUFF(
    (SELECT distinct ',' + QUOTENAME([Period]) FROM [MyTable] FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'')
PRINT @ColumnsList1
SET @ColumnsList2 = REPLACE (@ColumnsList1, ',','+')
PRINT @ColumnsList2
SET @ColumnsList3 = (
    SELECT distinct ',SUM(' + QUOTENAME([Period]) + ') as ' + QUOTENAME([Period])
    FROM [MyTable] FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
PRINT @ColumnsList3

SET @query = '
;With MyCTE as(
select [Name],'+@ColumnsList1+','+@ColumnsList2+' AS Grand_Total
from (
    SELECT [Name], [Quantity],[Period]
    FROM [MyTable]
) src
pivot
(
  SUM(Quantity)
  for Period in ('+@ColumnsList1+')
) piv
)
select ISNULL([Name],''Totoal'') as Name '+@ColumnsList3+',SUM([Grand_Total]) [Grand_Total]
from MyCTE
GROUP BY ROLLUP ([Name])
'
execute(@query)
GO

【讨论】:

  • 我确认它可以完成这项工作。我可以在底部没有总计的情况下生活。
  • 我没有注意到您在底部:-) 中询问了总计。我会在晚餐回来后添加它,但我想说的是,您的所有要求都毫无意义。您应该在客户端而不是服务器端进行。将更多数据从服务器传递到客户端有什么意义?!?如果您使用远程服务器,则意味着您通过互联网传递数据......这将减慢整个过程并导致服务器端有更多资源需要等待与客户端的连接
  • 完成:-) 如果这符合您的需要,您可以检查并将其标记为答案(但我建议阅读我之前的评论)
  • 有效。现在来看看动态 PIVOT。
  • excel 数据透视是在 excel 中完成的几个小时过程的一部分。我的老板希望它在 SQL 中自动化以缩短时间。这并不一定意味着我不同意你的观点。
猜你喜欢
  • 2021-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-16
  • 1970-01-01
  • 2021-09-18
相关资源
最近更新 更多