2017-04-07 43 views
3

我目前有這個查詢。過去爲我的要求工作。SQL - 修改查詢創建列

SELECT sites.sitename, 
    severity.severity, 
    COALESCE(Count(vulns.id), 0) AS Totals 
FROM sites 
    INNER JOIN systems 
      ON sites.id = systems.siteid 
    CROSS JOIN severity 
    LEFT JOIN vulns 
      ON vulns.systemid = systems.id 
      AND vulns.risk_factor = severity.severity 
GROUP BY sites.sitename, 
     severity.severity 

而這個返回的結果一樣

SiteName | Severity | Totals 
Orlando | Red  | 0 
Orlando | Yellow | 1 
Orlando | Green | 22 
Orlando | Orange | 1321 
Tampa | Red  | 22 
Tampa | Yellow | 111 
Tampa | Green | 223 
Tampa | Orange | 121 

我怎麼能修改此查詢打出來的嚴重程度成列。如

SiteName | Red | Yellow | Green | Orange 
Orlando | 0 | 1  | 22 | 1321 
+0

的嚴重性數量的限制?或者你有很多其他人嗎? –

+0

其他許多人。根本不受限制。我現在正在調查數據庫 –

回答

1

您可以使用條件聚集

SELECT sites.sitename, 
     Count(CASE WHEN severity.severity = 'Red' THEN vulns.id END) AS Red, 
     Count(CASE WHEN severity.severity = 'Yellow' THEN vulns.id END) AS Yellow, 
     Count(CASE WHEN severity.severity = 'Green' THEN vulns.id END) AS Green, 
     Count(CASE WHEN severity.severity = 'Orange' THEN vulns.id END) AS Orange  
FROM sites 
    INNER JOIN systems 
      ON sites.id = systems.siteid 
    CROSS JOIN severity 
    LEFT JOIN vulns 
      ON vulns.systemid = systems.id 
      AND vulns.risk_factor = severity.severity 
GROUP BY sites.sitename 

注:你不需要COALESCE因爲COUNT(NULL)回報0反正。

+0

非常感謝。還要感謝COALESCE和COUNT的說明 –

1

事實上,您在自己的表中擁有severity,這可以在沒有太多開銷的情況下實現動態變化。

使用動態條件彙總:

create table severity (severity varchar(32)); 
insert into severity values ('Red'),('Yellow'),('Green'),('Orange'); 

declare @cols nvarchar(max); 
declare @sql nvarchar(max); 
select @cols = stuff((
    select distinct 
     char(10)+'  , ' 
     + quotename(se.severity) 
     +' = sum(case when se.severity = '''+se.severity+''' then 1 else 0 end)' 
    from severity se 
    order by 1 
    for xml path (''), type).value('.','nvarchar(max)') 
    ,1,0,'') 
select @sql =' 
select 
    si.sitename'[email protected]+' 
FROM sites si 
    INNER JOIN systems sy 
      ON si.id = sy.siteid 
    CROSS JOIN severity se 
    LEFT JOIN vulns 
      ON vulns.systemid = systems.id 
      AND vulns.risk_factor = severity.severity 
GROUP BY si.sitename 
group by Id' 
select CodeGenerated = @sql 
--exec(@sql); 

rextester演示:http://rextester.com/TYDFP90293

查詢生成:

select 
    si.sitename 
    , [Green] = sum(case when se.severity = 'Green' then 1 else 0 end) 
    , [Orange] = sum(case when se.severity = 'Orange' then 1 else 0 end) 
    , [Red] = sum(case when se.severity = 'Red' then 1 else 0 end) 
    , [Yellow] = sum(case when se.severity = 'Yellow' then 1 else 0 end) 
FROM sites si 
    INNER JOIN systems sy 
      ON si.id = sy.siteid 
    CROSS JOIN severity se 
    LEFT JOIN vulns 
      ON vulns.systemid = systems.id 
      AND vulns.risk_factor = severity.severity 
GROUP BY si.sitename 
group by Id 
+0

非常有趣。謝謝。我也一定會考慮這一點 –

0
IF OBJECT_ID(N'tempdb..#temp') IS NOT NULL 
    DROP TABLE #temp 

;WITH cte1(SiteName , Severity , Totals) 
AS 
(
select 'Orlando' , 'Red'  , 0  Union all 
select 'Orlando' , 'Yellow' , 1  Union all 
select 'Orlando' , 'Green' , 22  Union all 
select 'Orlando' , 'Orange' , 1321 Union all 
select 'Tampa' , 'Red'  , 22  Union all 
select 'Tampa' , 'Yellow' , 111 Union all 
select 'Tampa' , 'Green' , 223 Union all 
select 'Tampa' , 'Orange' , 121 
) 
SELECT *INTO #temp FROM cte1 

SELECT SiteName, 
     MAX(CASE WHEN Severity = 'Red' THEN Totals END) Red, 
     MAX(CASE WHEN Severity = 'Yellow' THEN Totals END) Yellow, 
     MAX(CASE WHEN Severity = 'Green' THEN Totals END) Green, 
     MAX(CASE WHEN Severity = 'Orange' THEN Totals END) Orange 

    FROM #temp 
GROUP BY SiteName