2017-07-10 154 views
-1

我正在使用以下SQL來PIVOT數據時,這個SQL EXECUTE我得到的結果,但我也得到空值時,沒有特定日期的數據,因爲列是隨機生成我無法找到用0替換NULL值的方式。有人請幫助我這個。任何幫助將是偉大的。PIVOT列並用0替換空值

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 

回答

1

這也適用。我在你的查詢中創建了一個CTE,並傳入了一個select字符串以供使用。

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 
1

您需要從pivot()列列表生成您爲您select單獨列碼。

我將您現有的代碼轉換爲使用使用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 '[email protected] +' 
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 | 
+------------+---------------------+---------------------+---------------------+ 
0

您需要合併適用於選擇列表中的擺動列。因此,代碼生成的一些小調整將會訣竅

SET @query = '   
       SELECT department,'+ replace(replace(@cols,'[','coalesce(['),']','],0)') + ' FROM 
      (
       SELECT * FROM #Daysoftheweek 
      ) x 
      PIVOT 
      (
       avg(TotalUtilized) 
       FOR DayoftheWeek IN (' + @cols + ') 
      ) p  

      ' 
+0

Serg,當我執行這個SQL我缺少列名稱。以前我以日期時間作爲列名。但我在這裏錯過了那些列名稱。 – user3311323