SQL查询优化以在一个查询中获得结果

时间:2014-03-26 05:56:52

标签: sql sql-server sql-server-2008 tsql

我有两个以下的查询,我们每个月都不会发生严重的致命事故。

我们如何针对不同的事故类型优化并获得结果?

SELECT 
     COUNT(ICT.ID)      NoOfAccident,    
     YEAR(ICT.[Date])   AccidentYear,
     Month(ICT.[Date])  AccidentMonth,
     MAX(ICT.[Date])  AS    AccidentDate
    FROM
    Accidents ICT   
        Where   
        ICT.AccidentType    = "Serious"
        AND 
        ICT.[Date] > CONVERT(DATETIME, '09/20/13', 1)
    Group By
    YEAR(ICT.[Date]),
    Month(ICT.[Date])
    ORDER BY
    IncidentDate ASC


SELECT 
 COUNT(ICT.ID)      NoOfAccident,    
 YEAR(ICT.[Date])   AccidentYear,
 Month(ICT.[Date])  AccidentMonth,
 MAX(ICT.[Date])  AS    AccidentDate
FROM
Accidents ICT   
    Where   
    ICT.AccidentType    = "Fatal"
    AND 
    ICT.[Date] > CONVERT(DATETIME, '09/20/13', 1)
Group By
YEAR(ICT.[Date]),
Month(ICT.[Date])
ORDER BY
IncidentDate ASC

我们如何在一个查询中优化和获得结果,如:

NoOfSeriousAccident
NoOfFatalAccident
AccidentYear
AccidentMonth
AccidentDate 

3 个答案:

答案 0 :(得分:1)

琐碎 - 不仅按年份和月份分组,还按AccidentType分组(并删除每个查询的一个accidedenttype的过滤器)。

你每年/每月获得2行 - 每种事故类型一行。

答案 1 :(得分:0)

SELECT 
 ICT.AccidentType,
 COUNT(ICT.ID)      NoOfAccident,    
 YEAR(ICT.[Date])   AccidentYear,
 Month(ICT.[Date])  AccidentMonth,
 MAX(ICT.[Date])  AS    AccidentDate
FROM
Accidents ICT   
    Where   
    ICT.AccidentType IN ("Serious","Fatal")
    AND 
    ICT.[Date] > CONVERT(DATETIME, '09/20/13', 1)
Group By
ICT.AccidentType
YEAR(ICT.[Date]),
Month(ICT.[Date])
ORDER BY
IncidentDate ASC

编辑:根据更新的要求,您可以使用PIVOT为致命和严重事故计数获取单独的列,如下所示:

;with pivoted as
(select 
accidentyear, 
accidentmonth, 
serious as NoOfSeriousAccident, 
fatal as NoOfFatalAccident from
(SELECT 
 ICT.AccidentType,
 COUNT(ICT.ID)    cnt,
 YEAR(ICT.[accidentdate])   AccidentYear,
 Month(ICT.[accidentdate])  AccidentMonth
FROM
Accident ICT   
Where   
ICT.AccidentType IN ('Serious','Fatal')
AND 
ICT.[accidentdate] > CONVERT(DATETIME, '09/20/13', 1)
Group By
ICT.AccidentType,
YEAR(ICT.[accidentdate]),
Month(ICT.[accidentdate])) as s

pivot
(
max(cnt) 
for accidenttype in ([serious] ,[fatal])
) as pvt
)

select 
x.accidentyear, 
x.accidentmonth,
max(a.accidentdate), 
x.NoOfSeriousAccident, 
x.NoOfFatalAccident,
from pivoted x 
inner join accident a
on month(a.accidentdate) = x.accidentmonth
and year(a.accidentdate) = x.accidentyear
group by x.accidentmonth, x.accidentyear, x.seriouscount, x.fatalcount
order by max(a.accidentdate)

答案 2 :(得分:0)

;WITH CTE AS (
SELECT 
     COUNT(ICT.ID)      NoOfAccident,    
     YEAR(ICT.[Date])   AccidentYear,
     Month(ICT.[Date])  AccidentMonth,
     MAX(ICT.[Date])  AS    AccidentDate,
     ICT.AccidentType As AccidentType

    FROM
    Accidents ICT   
        Where   
        ICT.AccidentType    = "Serious"
        AND 
        ICT.[Date] > CONVERT(DATETIME, '09/20/13', 1)
    Group By
    YEAR(ICT.[Date]),
    Month(ICT.[Date])
    ORDER BY
    IncidentDate ASC

UNION ALL
SELECT 
 COUNT(ICT.ID)      NoOfAccident,    
 YEAR(ICT.[Date])   AccidentYear,
 Month(ICT.[Date])  AccidentMonth,
 MAX(ICT.[Date])  AS    AccidentDate,
 ICT.AccidentType  As AccidentType
FROM
Accidents ICT   
    Where   
    ICT.AccidentType    = "Fatal"
    AND 
    ICT.[Date] > CONVERT(DATETIME, '09/20/13', 1)
Group By
YEAR(ICT.[Date]),
Month(ICT.[Date])
ORDER BY
IncidentDate ASC

)

select NoOfAccident,AccidentYear,AccidentMonth,AccidentDate,AccidentType  from CTE 
WHERE  AccidentType IN ('Fatal','Serious')