基于字段旋转数据而不是对数据透视字段进行硬编码
Pivoting Data based on a field and not hard coding the pivot fields
ItemKey UpdatedOnHandQty AffectedDate
20406 1594.03 2013-12-27 00:00:00.000
20406 842.132 2014-01-09 00:00:00.000
20406 539.03 2014-02-11 00:00:00.000
20406 486.183 2014-05-12 00:00:00.000
20406 917.86 2014-06-27 00:00:00.000
20406 1314.209 2014-07-29 00:00:00.000
20406 512.261 2014-10-20 00:00:00.000
20406 1394.261 2014-11-12 00:00:00.000
20406 640.19 2014-12-30 00:00:00.000
20406 819.992 2014-08-11 00:00:00.000
我想在 sql 中转换此数据,而不必硬编码转换字段名称。我只希望每个唯一日期(年、月、日)都有一个字段名称。有没有一种方法可以根据这个字段进行调整,因为我有 100 个独特的情感日期。这最终将在 BI 工具中被过滤掉,但对于此报告,我需要对日期字段进行透视,而画面不允许在 excel 之外进行透视。
不幸的是,使用 SQL 服务器,您根本无法为动态 PIVOT's
或任何动态 SQL 创建 VIEW
。
存储过程可以让您做到这一点。
代码:(Demo)
DECLARE @sql NVARCHAR(MAX)
DECLARE @columns VARCHAR(MAX)
DECLARE @isNullColumns VARCHAR(MAX)
SET @sql = N''
SET @columns = ''
SET @isNullColumns = ''
; WITH item_dates AS
(
SELECT DISTINCT CONVERT(VARCHAR(10), AffectedDate, 112) AS AffectedDate
FROM table1
)
SELECT @columns += N',' + QUOTENAME(AffectedDate)
, @isNullColumns += N',ISNULL(' + QUOTENAME(AffectedDate) + ', 0) AS ' + QUOTENAME(AffectedDate)
FROM item_dates
ORDER BY AffectedDate
SET @columns = STUFF(@columns, 1, 1, '')
SET @isNullColumns = STUFF(@isNullColumns, 1, 1, '')
SET @sql = N'
;WITH cte AS
(
SELECT ItemKey
, CONVERT(VARCHAR(10), AffectedDate, 112) AS AffectedDate
, UpdatedOnHandQty
FROM table1
)
SELECT ItemKey
, ' + @isNullColumns + '
FROM cte
PIVOT
(
SUM(UpdatedOnHandQty) FOR AffectedDate IN (' + @columns + ')
) as p'
EXEC sp_executesql @sql;
解释:
- 为了能够动态执行此操作,您需要将动态 SQL 语句存储在变量中(例如:
@sql
)。
- 列的名称存储在变量 (
@columns
) 中,以便根据 AffectedDate
列的 DISTINCT
值动态构建列。
@isNullColumns
变量用于获取围绕 ISNULL()
函数的列名。否则,您的旋转数据可能会在输出中以 NULL's
结尾。
ItemKey UpdatedOnHandQty AffectedDate
20406 1594.03 2013-12-27 00:00:00.000
20406 842.132 2014-01-09 00:00:00.000
20406 539.03 2014-02-11 00:00:00.000
20406 486.183 2014-05-12 00:00:00.000
20406 917.86 2014-06-27 00:00:00.000
20406 1314.209 2014-07-29 00:00:00.000
20406 512.261 2014-10-20 00:00:00.000
20406 1394.261 2014-11-12 00:00:00.000
20406 640.19 2014-12-30 00:00:00.000
20406 819.992 2014-08-11 00:00:00.000
我想在 sql 中转换此数据,而不必硬编码转换字段名称。我只希望每个唯一日期(年、月、日)都有一个字段名称。有没有一种方法可以根据这个字段进行调整,因为我有 100 个独特的情感日期。这最终将在 BI 工具中被过滤掉,但对于此报告,我需要对日期字段进行透视,而画面不允许在 excel 之外进行透视。
不幸的是,使用 SQL 服务器,您根本无法为动态 PIVOT's
或任何动态 SQL 创建 VIEW
。
存储过程可以让您做到这一点。
代码:(Demo)
DECLARE @sql NVARCHAR(MAX)
DECLARE @columns VARCHAR(MAX)
DECLARE @isNullColumns VARCHAR(MAX)
SET @sql = N''
SET @columns = ''
SET @isNullColumns = ''
; WITH item_dates AS
(
SELECT DISTINCT CONVERT(VARCHAR(10), AffectedDate, 112) AS AffectedDate
FROM table1
)
SELECT @columns += N',' + QUOTENAME(AffectedDate)
, @isNullColumns += N',ISNULL(' + QUOTENAME(AffectedDate) + ', 0) AS ' + QUOTENAME(AffectedDate)
FROM item_dates
ORDER BY AffectedDate
SET @columns = STUFF(@columns, 1, 1, '')
SET @isNullColumns = STUFF(@isNullColumns, 1, 1, '')
SET @sql = N'
;WITH cte AS
(
SELECT ItemKey
, CONVERT(VARCHAR(10), AffectedDate, 112) AS AffectedDate
, UpdatedOnHandQty
FROM table1
)
SELECT ItemKey
, ' + @isNullColumns + '
FROM cte
PIVOT
(
SUM(UpdatedOnHandQty) FOR AffectedDate IN (' + @columns + ')
) as p'
EXEC sp_executesql @sql;
解释:
- 为了能够动态执行此操作,您需要将动态 SQL 语句存储在变量中(例如:
@sql
)。 - 列的名称存储在变量 (
@columns
) 中,以便根据AffectedDate
列的DISTINCT
值动态构建列。 @isNullColumns
变量用于获取围绕ISNULL()
函数的列名。否则,您的旋转数据可能会在输出中以NULL's
结尾。