我目前有这个查询。过去常常符合我的要求。
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 :(得分: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
。
答案 1 :(得分: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'+@cols+'
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
答案 2 :(得分: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