我想在使用数据透视表和动态列名的查询中使用0而不是空值

时间:2016-02-01 09:18:20

标签: sql-server tsql pivot

此查询返回按周和年分配的每个客户的销售额。通过这种方式,我可以得到不同年份的结果,而不会混合同一周不同年份的销售额。

但是在没有数据要显示的数周内我获得了NULL值,而是希望获得0。查询如下:

    DECLARE @DynamicPivotQuery AS NVARCHAR(MAX)
    DECLARE @ColumnName AS NVARCHAR(MAX)

    --Get distinct values of the PIVOT Column 
    SELECT @ColumnName= ISNULL(@ColumnName + ',','') 
    + QUOTENAME(courses.anomes)
    FROM 
    (
    SELECT DISTINCT right('0'+ltrim(rtrim(str(datepart(week,ft.fdata))))+'/'+ltrim(rtrim(str(ft.ftano))),7) anomes FROM ft where ftano=2015 
    ) Courses
    order by anomes

    --Prepare the PIVOT query using the dynamic 
    SET @DynamicPivotQuery = 
      N'SELECT nome, ' + @ColumnName + '
        FROM 
        (
        select nome,
right('+'''0'''+'+ltrim(rtrim(str(datepart(week,ft.fdata))))+'+'''/'''+'+ltrim(rtrim(str(ft.ftano))),7) anomes,etotal from ft where ftano=2015
        ) p
PIVOT(SUM(Etotal) 
      FOR anomes IN (' + @ColumnName + ')) AS PVTTable'
      --Execute the Dynamic Pivot Query
      EXEC sp_executesql @DynamicPivotQuery

1 个答案:

答案 0 :(得分:2)

Public Sub testTransactions() On Error GoTo err Dim wrk As DAO.Workspace Dim rollback As Boolean Set wrk = DBEngine.Workspaces(0) With wrk .BeginTrans CurrentDb.Execute "INSERT INTO sys_test (myName) VALUES ('Parent')", dbFailOnError testChildTransaction .CommitTrans End With exit_f: On Error GoTo 0 If rollback Then wrk.rollback MsgBox "Rollback Achieved" End If wrk.Close Set wrk = Nothing Exit Sub err: MsgBox "Error" rollback = True Resume exit_f End Sub 类似,创建一个@ColumnName,选择@ColumnNameSelect并在ISNULL(pivot_col,0)子句中使用它。

更新由于某些基本信息缺失(如SELECT表),我无法测试我的答案。我用STUFF重新编写了ft这是一种更好的方法。您应该将这种工作方式应用于构建@ColumnNameSelect列表。为了测试这个,我创建了一个临时表@ColumnName来代替你的#ft表。要运行此操作,请在脚本中将ft替换为#ft AS ft

ft

打印出来:

CREATE TABLE #ft(fdata DATETIME,ftano INT,nome VARCHAR(256),etotal INT); 
INSERT INTO #ft(fdata,ftano,nome,etotal)VALUES
    ('20151220',2015,'nome1',16),
    ('20151201',2015,'nome2',9),
    ('20151116',2015,'nome3',25),
    ('20151010',2015,'nome4',11);

DECLARE @DynamicPivotQuery AS NVARCHAR(MAX);
DECLARE @ColumnName AS NVARCHAR(MAX);

--Get distinct values of the PIVOT Column 
SELECT @ColumnName= ISNULL(@ColumnName + ',','') 
+ QUOTENAME(courses.anomes)
FROM 
(
SELECT DISTINCT right('0'+ltrim(rtrim(str(datepart(week,ft.fdata))))+'/'+ltrim(rtrim(str(ft.ftano))),7) anomes FROM #ft AS ft where ftano=2015 
) Courses
order by anomes

DECLARE @ColumnNameSelect AS NVARCHAR(MAX)
SELECT @ColumnNameSelect=STUFF((
    SELECT
    ',ISNULL('+QUOTENAME(courses.anomes)+',0) AS '+QUOTENAME(courses.anomes)
    FROM 
    (
    SELECT DISTINCT right('0'+ltrim(rtrim(str(datepart(week,ft.fdata))))+'/'+ltrim(rtrim(str(ft.ftano))),7) anomes FROM #ft AS ft where ftano=2015 
    ) Courses
    order by anomes
    FOR XML PATH('')
    ),1,1,'');
PRINT @ColumnNameSelect

--Prepare the PIVOT query using the dynamic 
SET @DynamicPivotQuery = 
    N'SELECT nome, ' + @ColumnNameSelect + '
    FROM 
    (
    select nome,
right('+'''0'''+'+ltrim(rtrim(str(datepart(week,ft.fdata))))+'+'''/'''+'+ltrim(rtrim(str(ft.ftano))),7) anomes,etotal from #ft AS ft where ftano=2015
    ) p
PIVOT(SUM(Etotal) 
    FOR anomes IN (' + @ColumnName + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
EXEC sp_executesql @DynamicPivotQuery;

DROP TABLE #ft;