我正在使用以下SQL来PIVOT数据当这个sql EXECUTE我得到结果但我也得到Null值时没有特定日期的数据,因为列是随机生成我无法找到用0替换NULL值的方法。有人请帮助我。任何帮助都会很棒。
drop table #Daysoftheweek
create table #Daysoftheweek
(department varchar(10),TotalUtilized int,DayoftheWeek varchar(30))
insert into #Daysoftheweek
VALUES ('ER','0',convert (varchar(30),GETDATE()-1,120))
,('ICU','1',convert (varchar(30),GETDATE()-1,120))
,('ICU','1',convert (varchar(30),GETDATE()-2,120))
,('CICU','0',convert (varchar(30),GETDATE()-3,120))
DECLARE @cols NVARCHAR (MAX)
DECLARE @query NVARCHAR(MAX)
SELECT @cols = COALESCE (@cols + ',[' + CONVERT(NVARCHAR, DayoftheWeek, 106) + ']',
'[' + CONVERT(NVARCHAR, DayoftheWeek, 106) + ']')
FROM (SELECT DISTINCT DayoftheWeek FROM #Daysoftheweek) PV
ORDER BY DayoftheWeek
SET @query = '
SELECT * FROM
(
SELECT * FROM #Daysoftheweek
) x
PIVOT
(
avg(TotalUtilized)
FOR DayoftheWeek IN (' + @cols + ')
) p
'
EXEC SP_EXECUTESQL @query
答案 0 :(得分:1)
您需要与select
列列表分开生成pivot()
列的代码。
我已将您现有的代码转换为使用stuff()
with select ... for xml path ('')
method of string concatenation。
declare @cols nvarchar (max), @selectcols nvarchar(max), @query nvarchar(max);
set @cols = stuff((
select distinct ', ' + quotename(convert(nvarchar(30),DayoftheWeek,106))
from #Daysoftheweek
for xml path (''), type).value('(./text())[1]','nvarchar(max)')
,1,2,'');
set @selectcols = (
select distinct char(10)+' , ' + quotename(convert(nvarchar(30),DayoftheWeek,106))
+' = isnull(' + quotename(convert(nvarchar(30),DayoftheWeek,106)) + ',0)'
from #Daysoftheweek
for xml path (''), type).value('(./text())[1]','nvarchar(max)')
set @query = '
select
Department '+@selectcols +'
from (select * from #Daysoftheweek) x
pivot (avg(TotalUtilized)for DayoftheWeek in (' + @cols + ')) p';
select CodeGenerated = @query;
exec sp_executesql @query;
rextester演示:http://rextester.com/DQET60056
代码生成:
select
Department
, [2017-07-07 18:17:25] = isnull([2017-07-07 18:17:25],0)
, [2017-07-08 18:17:25] = isnull([2017-07-08 18:17:25],0)
, [2017-07-09 18:17:25] = isnull([2017-07-09 18:17:25],0)
from (select * from #Daysoftheweek) x
pivot (avg(TotalUtilized)for DayoftheWeek in ([2017-07-07 18:17:25], [2017-07-08 18:17:25], [2017-07-09 18:17:25])) p
返回:
+------------+---------------------+---------------------+---------------------+
| Department | 2017-07-07 18:17:25 | 2017-07-08 18:17:25 | 2017-07-09 18:17:25 |
+------------+---------------------+---------------------+---------------------+
| cicu | 0 | 0 | 0 |
| er | 0 | 0 | 0 |
| icu | 0 | 1 | 1 |
+------------+---------------------+---------------------+---------------------+
答案 1 :(得分:1)
这也有效。我在您的查询中创建了一个CTE,并传入了一个要使用的选择字符串。
CREATE TABLE #Daysoftheweek
(department VARCHAR(10),TotalUtilized INT,DayoftheWeek VARCHAR(30))
--Put dates into varchar variable
DECLARE @date1 VARCHAR(30) = CONVERT (VARCHAR(30),GETDATE()-1,120)
DECLARE @date2 VARCHAR(30) = CONVERT (VARCHAR(30),GETDATE()-2,120)
DECLARE @date3 VARCHAR(30) = CONVERT (VARCHAR(30),GETDATE()-3,120)
--Create Select string for later
DECLARE @selectString VARCHAR(MAX) = 'department,[' +
@date3 + '] = isnull([' + @date3 + '],0), [' +
@date2 + '] = isnull([' + @date2 + '],0), [' +
@date1 + '] = isnull([' + @date1 + '],0)'
INSERT INTO #Daysoftheweek
VALUES ('ER','0',@date1)
,('ICU','1',@date1)
,('ICU','1',@date2)
,('CICU','0',@date3)
DECLARE @cols NVARCHAR (MAX)
DECLARE @query NVARCHAR(MAX)
SELECT @cols = COALESCE (@cols + ',[' + CONVERT(NVARCHAR, DayoftheWeek, 106) + ']',
'[' + CONVERT(NVARCHAR, DayoftheWeek, 106) + ']')
FROM (SELECT DISTINCT DayoftheWeek FROM #Daysoftheweek) PV
ORDER BY DayoftheWeek
--Query with CTE and using @selectString created above
SET @query = 'WITH preselect AS (
SELECT * FROM
(
SELECT * FROM #Daysoftheweek
) x
PIVOT
(
avg(TotalUtilized)
FOR DayoftheWeek IN (' + @cols + ')
) p )
SELECT ' + @selectString + '
FROM preselect'
EXEC SP_EXECUTESQL @query
DROP TABLE #Daysoftheweek
答案 2 :(得分:0)
您需要将Coalesce应用于选择列表中的透视列。所以对代码生成进行一些调整就可以了解
(2)