带枢轴的动态 sql

Dynamic sql with pivot

我有图片中的数据..

类型将根据类型 ID 选择而改变,

我正在尝试实现和输出类似于以下内容:-

166su01count 对应于类型 166su01,它应该显示日期 4/16/2018 的 5(总天数)

166su01Rate 对应于类型 166su01,它应该显示日期 4/16/2018 的 60.00(percount)

166su02count 对应于类型 166su02,它应该显示日期 4/16/2018 的 7(总天数)

166su02Rate 对应于类型 166su02,对于日期 4/16/2018 它应该显示 28.57(percount) 等等……

类型根据选择而变化请帮助..

为MS-SQL服务器提供解决方案-

正在创建 table 和数据 -

CREATE TABLE [dbo].[Type](
    [daynumbers] [date] NULL,
    [daystotal] [int] NULL,
    [types] [varchar](15) NULL,
    [percount] [float] NULL
) ON [PRIMARY]


INSERT INTO [dbo].[Type]
           ([daynumbers]
           ,[daystotal]
           ,[types]
           ,[percount])
     VALUES
('2018-04-16',  5   ,'166su01', 60)
,('2018-04-16', 7   ,'166su02', 28.57)
,('2018-04-18', 8   ,'166su02', 62.5)
,('2018-04-19', 5   ,'166su01', 100)

问题分为两部分 -

  1. 从单个列(类型)进行多个数据透视(一个用于 percount ,一个用于 daystotal )
  2. 使查询适用于动态 sql

第 1 部分 -

这可以通过复制 types 列并将其命名为 types1 并旋转 table 两次来解决 - 一个用于 percount,一个用于 daystotal

SELECT *
FROM
(SELECT *,types+' Count'[types1] FROM dbo.Type) AS SourceTable --duplicate column created here

PIVOT  
(  
SUM(percount) 
FOR types IN ([166su01], [166su02])  
) AS PivotTable
PIVOT  
(  
SUM(daystotal) 
FOR types1 IN ([166su01 Count], [166su02 Count])  
) AS PivotTable

这将创建额外的行 因此,按以下方式使用 daynumbers 列对它们进行分组 -

SELECT daynumbers,Sum([166su01])[166su01],Sum( [166su01 Count]) [166su01 Count], Sum([166su02])[166su02],Sum( [166su02 Count]) [166su02 Count] FROM  
(SELECT *,types+' Count'[types1] FROM dbo.Type) AS SourceTable

PIVOT  
(  
SUM(percount) 
FOR types IN ([166su01], [166su02])  
) AS PivotTable
PIVOT  
(  
SUM(daystotal) 
FOR types1 IN ([166su01 Count], [166su02 Count])  
) AS PivotTable
group by
daynumbers

第 2 部分 - 使这个查询动态化 需要动态定义以下项目 -

    Select 查询的
  1. Headers - Sum([166su01])[166su01],Sum([166su01 Count]) [166su01 Count], Sum([166su02])[166su02], Sum( [166su02 计数]) [166su02 计数]
  2. Percount Pivot - [166su01]、[166su02]
  3. 枢轴总天数 - [166su01 计数],[166su02 计数]

这可以通过 -

DECLARE @PivotPercount NVARCHAR(MAX) = N'' --Variable to hold types to pivot for percount
SELECT @PivotPercount = @PivotPercount + ', [' + COALESCE(types, '') + ']' FROM (SELECT DISTINCT types FROM dbo.Type)DT
SELECT @PivotPercount = LTRIM(STUFF(@PivotPercount, 1, 1, '')) --Remove first comma and space
print @PivotPercount

DECLARE @PivotDaysTotal NVARCHAR(MAX) = N'' --Variable to hold types to pivot for daystotal
SELECT @PivotDaysTotal = @PivotDaysTotal + ', [' + COALESCE(types, '') + ' Count]' FROM (SELECT DISTINCT types FROM dbo.Type)DT
SELECT @PivotDaysTotal = LTRIM(STUFF(@PivotDaysTotal, 1, 1, '')) --Remove first comma and space
print @PivotDaysTotal

DECLARE @Headers NVARCHAR(MAX) = N'' --Variable to hold unique customers to be used in PIVOT clause
SELECT @Headers = @Headers + ', Sum([' + COALESCE(types, '') + '])'+'[' + COALESCE(types, '') + ']' + ',Sum( [' + COALESCE(types, '') + ' Count]) ' + '[' + COALESCE(types, '') + ' Count]'   FROM (SELECT DISTINCT types FROM dbo.Type)DT
SELECT @Headers = LTRIM(STUFF(@Headers, 1, 1, '')) --Remove first comma and space
print @Headers

现在结合一切 - 最终查询 -

DECLARE @PivotPercount NVARCHAR(MAX) = N'' --Variable to hold types to pivot for percount
SELECT @PivotPercount = @PivotPercount + ', [' + COALESCE(types, '') + ']' FROM (SELECT DISTINCT types FROM dbo.Type)DT
SELECT @PivotPercount = LTRIM(STUFF(@PivotPercount, 1, 1, '')) --Remove first comma and space
print @PivotPercount

DECLARE @PivotDaysTotal NVARCHAR(MAX) = N'' --Variable to hold types to pivot for daystotal
SELECT @PivotDaysTotal = @PivotDaysTotal + ', [' + COALESCE(types, '') + ' Count]' FROM (SELECT DISTINCT types FROM dbo.Type)DT
SELECT @PivotDaysTotal = LTRIM(STUFF(@PivotDaysTotal, 1, 1, '')) --Remove first comma and space
print @PivotDaysTotal

DECLARE @Headers NVARCHAR(MAX) = N'' --Variable to hold unique customers to be used in PIVOT clause
SELECT @Headers = @Headers + ', Sum([' + COALESCE(types, '') + '])'+'[' + COALESCE(types, '') + ']' + ',Sum( [' + COALESCE(types, '') + ' Count]) ' + '[' + COALESCE(types, '') + ' Count]'   FROM (SELECT DISTINCT types FROM dbo.Type)DT
SELECT @Headers = LTRIM(STUFF(@Headers, 1, 1, '')) --Remove first comma and space
print @Headers

DECLARE @SQLStatement NVARCHAR(MAX) = N'' --Variable to hold t-sql query
--Generate dynamic PIVOT query here
SET @SQLStatement =
N'SELECT daynumbers,' + @Headers +
' FROM  
(SELECT *,types+'' Count''[types1] FROM dbo.Type) AS SourceTable

PIVOT  
(  
SUM(percount) 
FOR types IN ('+ @PivotPercount +')  
) AS PivotTable
PIVOT  
(  
SUM(daystotal) 
FOR types1 IN (' + @PivotDaysTotal + ')  
) AS PivotTable
group by
daynumbers
'
print @SQLStatement
--Execute the dynamic t-sql PIVOT query below
EXEC (@SQLStatement)

如果觉得有用请为答案投票