我希望在使用 pivot table 和动态列名的查询中使用 0 而不是空值
I want 0s instead of null values in query using pivot table and dynamic column names
此查询returns 每个客户的销售额按周和年分布。这样我就可以得到不同年份的结果,而无需在同一周内混合不同年份的销售额。
但是我在没有数据显示的那几周得到了 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
类似于 @ColumnName
,创建一个选择 ISNULL(pivot_col,0)
的 @ColumnNameSelect
并在您的 SELECT
子句中使用它。
更新 由于缺少一些基本信息(例如 ft
table),我无法测试我回答的内容。我使用 STUFF 重写了 @ColumnNameSelect
,这是一种更好的方法。您也应该将这种工作方式应用于构建 @ColumnName
列表。为了测试这个,我创建了一个临时的 table #ft
来代替你的 ft
table。 运行 将脚本中的 #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;
打印出来:
+-------+---------+---------+---------+---------+
| nome | 41/2015 | 47/2015 | 49/2015 | 52/2015 |
+-------+---------+---------+---------+---------+
| nome1 | 0 | 0 | 0 | 16 |
| nome2 | 0 | 0 | 9 | 0 |
| nome3 | 0 | 25 | 0 | 0 |
| nome4 | 11 | 0 | 0 | 0 |
+-------+---------+---------+---------+---------+
此查询returns 每个客户的销售额按周和年分布。这样我就可以得到不同年份的结果,而无需在同一周内混合不同年份的销售额。
但是我在没有数据显示的那几周得到了 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
类似于 @ColumnName
,创建一个选择 ISNULL(pivot_col,0)
的 @ColumnNameSelect
并在您的 SELECT
子句中使用它。
更新 由于缺少一些基本信息(例如 ft
table),我无法测试我回答的内容。我使用 STUFF 重写了 @ColumnNameSelect
,这是一种更好的方法。您也应该将这种工作方式应用于构建 @ColumnName
列表。为了测试这个,我创建了一个临时的 table #ft
来代替你的 ft
table。 运行 将脚本中的 #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;
打印出来:
+-------+---------+---------+---------+---------+
| nome | 41/2015 | 47/2015 | 49/2015 | 52/2015 |
+-------+---------+---------+---------+---------+
| nome1 | 0 | 0 | 0 | 16 |
| nome2 | 0 | 0 | 9 | 0 |
| nome3 | 0 | 25 | 0 | 0 |
| nome4 | 11 | 0 | 0 | 0 |
+-------+---------+---------+---------+---------+