下面的SELECT语句来自存储过程我用来检索随后发送给JSON的数据:
SELECT *
FROM (
SELECT CAST(DateTimeUTC as SmallDateTime) as [DateTime], DataValue, VariableID
FROM DataValues
WHERE SiteID = @siteID and VariableID BETWEEN 9 and 10 and DateTimeUTC >= DATEADD (day, @pastDays, getdate())
) TableDate
PIVOT (SUM(DataValue) FOR VariableID IN ([9],[10])) PivotTable ORDER BY [DateTime]
我想要完成的是修改程序以接受要转动的列范围。在上面的例子中,我只检索两个变量的值。如果我想检索VariableID 1到10或1到50,该怎么办?必须有一种方法可以通过以下方式检索1到10:
VariableID IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10])
MSDN上的Using PIVOT and UNPIVOT未提及指定范围的方法。
我意识到可以在存储过程中使用动态SQL,但鉴于我自己对SQL的了解以及那些必须长期维护的人的知识,我对通过使用动态SQL引入额外的复杂性犹豫不决。这里有一个概念上类似的问题,请参阅TSQL Pivot Long List of Columns,并通过动态SQL解决方案回答。
答案 0 :(得分:6)
不幸的是,PIVOT
函数无法使用动态sql生成列列表。
所以你的SQL代码将类似于:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(VariableID)
from DataValues
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT [DateTime], ' + @cols + ' from
(
SELECT CAST(DateTimeUTC as SmallDateTime) as [DateTime],
DataValue,
VariableID
FROM DataValues
WHERE SiteID = '+cast(@siteID as varchar(10))+'
-- and VariableID BETWEEN 9 and 10 -- remove the variableID filter
and DateTimeUTC >= DATEADD (day, +'cast(@pastDays as varchar(10))+', getdate())
) x
pivot
(
SUM(DataValue)
for VariableID in (' + @cols + ')
) p '
execute(@query)
关键是以下代码生成variableIds
列表成为列:
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(VariableID)
from DataValues
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
这将创建所有distinct
变量ID的列表。然后将此列表添加到SQL查询字符串以返回。