2017-04-07 45 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