Оператор PIVOT
работает с набором постоянных значений. Эти значения должны быть явно записаны и не могут ссылаться на другие столбцы, содержать выражения или функции, такие как ISNULL
.
DECLARE @Mascot TABLE (
Amount INT,
Mascot VARCHAR(100))
INSERT INTO @Mascot (
Amount,
Mascot)
VALUES
(10, 'Dog'), (5, 'Dog'),
(6, 'Cat'),
(12, 'Weird Spider'), (8, 'Weird Spider'), (5, 'Weird Spider')
SELECT
P.*
FROM
@Mascot AS M
PIVOT (
SUM(M.Amount)
FOR Mascot IN ([Dog], [Cat], [Weird Spider], [Cameleon])
) AS P
Результат:
Dog Cat Weird Spider Cameleon
15 6 25 NULL
После поворота таблицы значения этих констант теперь равны столбцам , а их имена в качестве константы, которую мы использовали для их поворота:
SELECT
P.Dog, -- We can reference the pivoted columns by name
P.Cat,
P.[Weird Spider],
P.Cameleon
FROM
@Mascot AS M
PIVOT (
SUM(M.Amount)
FOR Mascot IN ([Dog], [Cat], [Weird Spider], [Cameleon])
) AS P
Мы можем сделать любую модификацию, какую захотим, в качестве выражения в списке столбцов SELECT
:
SELECT
P.Dog,
P.Cat,
P.[Weird Spider],
ISNULL(P.Cameleon, 0) AS Cameleon,
Total =
ISNULL(P.Dog, 0) +
ISNULL(P.Cat, 0) +
ISNULL(P.[Weird Spider], 0) +
ISNULL(P.Cameleon, 0)
FROM
@Mascot AS M
PIVOT (
SUM(M.Amount)
FOR Mascot IN ([Dog], [Cat], [Weird Spider], [Cameleon])
) AS P
Результат:
Dog Cat Weird Spider Cameleon Total
15 6 25 0 46
Таким образом, когда вы строите свой динамический свод, значения сводки должны быть точным содержанием значения, хранящегося в наборе, который вы собираетесь сводить ('Dog'
, 'Cat'
и т. Д.), В то время как на SELECT
список вы можете построить любое выражение, которое вы хотите (ISNULL([Dog], 0) AS [Dog]
).
Таким образом, решение для вашего случая состоит в том, чтобы использовать 2 разных @cols
, один с нулевыми проверками в списке SELECT
, а другой для поворота значений.
DECLARE @cols_select AS NVARCHAR(MAX),
@cols_pivot AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
SELECT @cols_pivot = STUFF((SELECT ',' + QUOTENAME(TagID)
FROM [table]
GROUP BY TagID
ORDER BY TagID
FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')
SELECT @cols_select = STUFF((SELECT ','', IsNull(' + QUOTENAME(TagID)+', 0) as '+QUOTENAME(TagID)
FROM [table]
GROUP BY TagID
ORDER BY TagID
FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')
SET @query = 'SELECT TimeStamp, ' + @cols_select + ' from
(
select DATEADD(minute,DATEDIFF(minute,0,TimeStamp)/5*5,0) AS TimeStamp, TagID , ISNULL(TRY_CAST(TagValue AS DECIMAL(18,2)),0) AS TagValue
from [table]
-- Where TagValue isnull(TagValue,1)=0
Group By datediff(minute, 0,Timestamp)/5,TagID, TagValue
) x
pivot
(
AVG(TagValue)
for TagID in ( ' + @cols_pivot + ' )
) p '
EXEC(@query)