在数据透视表中将NULL替换为avg CAST

时间:2019-06-05 08:11:46

标签: sql sql-server datetime pivot-table isnull

我正在尝试将与AVG Cast结合在一起的TagValue列的输出中的NULL替换为0。 我尝试了以下查询:

ISNULL(TRY_CAST(TagValue AS DECIMAL(18,2)),0) AS TagValue 

在代码中


DECLARE @cols AS NVARCHAR(MAX),
        @query AS NVARCHAR(MAX)

SELECT @cols = STUFF((SELECT  ',' + QUOTENAME(TagID)
                      FROM [table]
                      GROUP BY TagID
                      ORDER BY TagID
                FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')

SET @query = 'SELECT   TimeStamp,  ' + @cols + ' 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 + ' )
            ) p '

EXEC(@query)


尽管没有错误,查询输出仍显示NULL。

我还尝试了以下查询:


SELECT @cols = 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,  ' +ISNULL(@cols,0) + ' from ...

还有Case函数:

CASE When (TagValue= NULL) THEN 0 ELSE TRY_CAST(TagValue AS DECIMAL(18,2)) END AS TagValue

非常感谢您的帮助! 非常感谢

1 个答案:

答案 0 :(得分:1)

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)
相关问题