2015-08-18 173 views
0

我现在有一个SQL查询,看起来像这样每个日期:SQL查询范围

SELECT CONVERT(DECIMAL(5,1),(
    CONVERT(DECIMAL(6,1),(
     SELECT COUNT(*) 
     FROM Requests 
     LEFT JOIN RequestSLA ON Requests.RequestId = RequestSLA.RequestId 
     WHERE DateLogged between '2015/03/01' and '2015/08/17' 
     AND RespondBy <= Responded 
    ))/CONVERT(DECIMAL(6,1),(
     SELECT COUNT(*) 
     FROM Requests 
     WHERE DateLogged between '2015/03/01' and '2015/08/17' 
    ))) 
*100) 

这将返回票是违反了回应SLA(这里是RespondBy之后有反应)的所有门票的百分比在提供的日期范围内。是否可以修改此查询以分别显示每天的百分比? I.E.是这样的:

Date  Percentage 
2015-03-01 10 
2015-03-02 7 

等等

我试图用一个GROUP BY条款,但这并没有工作,因为DateLogged(这是什么,我会通过被分组)不包括在声明

+0

为什么两个'CONVERT()'? – Barranka

回答

3

使用一个单一的查询,而不是两个相关子查询的输出,那么你可以使用GROUP BY DateLogged,你只需把你的计数的一个范围内的情况下表达:

SELECT r.DateLogged, 
     Total = COUNT(*), 
     BreachedSLA = COUNT(CASE WHEN sla.RespondBy <= sla.Responded THEN 1 END), 
     PercentBreached = CONVERT(DECIMAL(6, 1), 100.0 * COUNT(CASE WHEN sla.RespondBy <= sla.Responded THEN 1 END)/COUNT(*)) 
FROM Requests AS r 
     LEFT JOIN RequestSLA AS sla 
      ON r.RequestId = sla.RequestId 
WHERE r.DateLogged >= '20150301' 
AND  r.DateLogged <= '20150817' 
GROUP BY r.DateLogged; 

注意,我已将您的日期格式更改为完全独立于文化的格式yyyyMMdd,这是SQL Server中DATETIMESMALLDATETIME的唯一独立格式,因此虽然边界不太清晰,但它保证了正确的转换,并且某些区域设置的格式为yyyy/MM/dd会抛出一个错误,或者更糟的是它会被转换为一个无意的日期。

SET DATEFORMAT DMY; 
SELECT CONVERT(DATETIME, '2015/08/17') 

我也改变了你的BETWEEN子句>=<=,不是因为它有什么不同,而是因为它更容易转换成开放式的日期范围,例如

WHERE r.DateLogged >= '20150301' 
AND  r.DateLogged < '20150818' 

随着between '2015/03/01' and '2015/08/17',你可能会得到一个登录日期的2015/08/17 10:00,未返回,而且往往是不直观的,为什么。有关更多阅读,请参阅What do BETWEEN and the devil have in common?

+0

喜欢sqlblog文章的名称。我刚刚发现,我可能需要为任何“已关闭”票证查询第二组表格。这可以通过在最后的WHERE子句上面添加一个'UNION SELECT'来完成,并且复制要选择的列,或者有更好的方法来完成吗? – CyberJacob

+0

shold你没有使用'count(distinct r.RequestId)'而不是'count(*)'? –

+0

我还应该指出,你想'sla.Responded',而不是'r.Responded' – CyberJacob