如何在动态数据透视查询中用空字符串替换NULL值

时间:2019-07-08 23:25:27

标签: sql sql-server

我有这个动态查询:

DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX),
        @archivedate date = '5/1/2019'; 

WITH 
E(n) AS(
    SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0))E(n)
),
E2(n) AS(
    SELECT a.n FROM E a, E b
),
E4(n) AS(
    SELECT a.n FROM E2 a, E2 b
),
cteTally(n) AS(
    SELECT TOP((SELECT TOP (1) COUNT(DISTINCT ratechangedate) datecount
                FROM MARS_DW.[dbo].[vw_GTMScheduledRateAndPaymentChangesWithAccountNumber_Archive]
                WHERE ArchiveDate = @archivedate
                GROUP BY account
                ORDER BY datecount DESC)) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) n
    FROM E4
)        
SELECT @cols = (SELECT REPLACE( '
    ,MIN( CASE WHEN index_num = <<index_num>> THEN ratechangedate END) AS [date <<index_num>>]
    ,MIN( CASE WHEN index_num = <<index_num>> THEN new_noterate END)   AS [rate <<index_num>>]' , '<<index_num>>', n)
            FROM cteTally
            ORDER BY n
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 

set @query = 
N'WITH a AS (
    SELECT a.account,
        dense_rank() OVER ( PARTITION BY a.account ORDER BY ratechangedate) AS index_num,
        CONVERT(VARCHAR(10),ratechangedate,101)[ratechangedate],
        new_noterate
    FROM MARS_DW.[dbo].[vw_GTMScheduledRateAndPaymentChangesWithAccountNumber_Archive] a
    WHERE archivedate = @date
    )
SELECT a.account' + @cols + N' 
FROM a
GROUP BY a.Account;'


EXECUTE sp_executesql @query, N'@date datetime', @date = @archivedate;

哪个产生以下输出:

enter image description here

我想删除NULL值并将其替换为空字符串,我尝试将ISNULL(CONVERT(VARCHAR(10),ratechangedate,101),'')ISNULL(new_noterate,'')放在代码的@query部分中,但出现以下错误:

  

第207级,州立1,第10行,
  无效的列名“ ratechangedate”。

     

第207级状态1的12行消息
  无效的列名“ ratechangedate”。

     

第207条消息,第16级,状态1,第14行
  无效的列名“ ratechangedate”。

     

............以此类推,每隔一行“。”直到34 .......

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

尝试一下:

DECLARE @cols NVARCHAR(MAX), @query NVARCHAR(MAX), @archivedate DATE = '2019-01-05'; 

DECLARE @HowMany INT = 
                (
                    SELECT TOP(1) COUNT(DISTINCT a.ratechangedate) AS [datecount]
                    FROM MARS_DW.[dbo].[vw_GTMScheduledRateAndPaymentChangesWithAccountNumber_Archive] a
                    WHERE a.ArchiveDate = @archivedate
                    GROUP BY a.account
                    ORDER BY [datecount] DESC
                )
;
WITH E(n) AS (SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0))E(n))
    ,E2(n) AS (SELECT a.n FROM E a CROSS JOIN E b)
    ,E4(n) AS (SELECT a.n FROM E2 a CROSS JOIN E2 b)
    ,cteTally(n) AS (SELECT TOP(@HowMany) ROW_NUMBER()OVER(ORDER BY (SELECT NULL)) n FROM E4)      
SELECT @cols = (SELECT REPLACE( N'
    ,COALESCE(CONVERT(NVARCHAR(255),MIN( CASE WHEN index_num = <<index_num>> THEN ratechangedate END)),'''') AS [date <<index_num>>]
    ,COALESCE(CONVERT(NVARCHAR(255),NULLIF(MIN( CASE WHEN index_num = <<index_num>> THEN new_noterate END),0)),'''') AS [rate <<index_num>>]
                ' 
                , '<<index_num>>', n)
            FROM cteTally
            ORDER BY n
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
;

SET @query = 
N'WITH ct AS (
    SELECT a.account
        ,DENSE_RANK()OVER(PARTITION BY a.account ORDER BY a.ratechangedate) AS [index_num]
        ,CONVERT(VARCHAR(10),a.ratechangedate,101) AS [ratechangedate]
        ,a.new_noterate
    FROM MARS_DW.[dbo].[vw_GTMScheduledRateAndPaymentChangesWithAccountNumber_Archive] a
    WHERE a.archivedate = @date
)
SELECT ct.Account' + @cols + N' 
FROM ct
GROUP BY ct.Account;'

--PRINT @query;

EXECUTE sp_executesql @query, N'@date DATETIME', @date = @archivedate;