改进SQL Server查询

时间:2014-11-24 15:46:44

标签: sql sql-server

我必须改进这个查询,这非常有用。

DECLARE     @timTimeout int, 
        @iniDate varchar(20), 
        @endDate varchar(20)            
SET         @iniDate = '2014-07-20 00:00:00'              
SET         @endDate = '2014-11-24 23:59:59'           
SET         @timTimeout = 4000                       

SET ANSI_WARNINGS OFF

SELECT 
            'Approved (0200)' = ISNULL(SUM(CASE CodMsgIncome WHEN '0200' THEN 1 END), 0),
            'Approved Off (0220)' = ISNULL(SUM(CASE CodMsgIncome WHEN '0220' THEN 1 END), 0),
            'Cancel (0400)' = ISNULL(SUM(CASE CodMsgIncome WHEN '0400' THEN 1 END), 0),
            'Regret (0420)' = ISNULL(SUM(CASE CodMsgIncome WHEN '0420' THEN 1 END), 0),
            'TOTAL' = COUNT(*),
            'Time-outs' = ISNULL(SUM(CASE WHEN DATEDIFF(ms, DateMsgIncome, DateMsgSent) > @timTimeout THEN 1 END), 0),
            'Disponibility (%)' = (1 - CAST(ISNULL(SUM(CASE WHEN DATEDIFF(ms, DateMsgIncome, DateMsgSent) > @timTimeout THEN 1 END), 0) as money) / COUNT(*)) * 100
FROM Message (NOLOCK)
    WHERE DateMsgIncome BETWEEN @iniDate AND @endDate
            AND CodMsgIncome IN ('0200', '0220', '0400', '0420', '0800', '0900', '9080', '9085') 
            AND DescMsgIncome <> '0220'

现在,我必须准备一份包含按月组织的总数据的报告。

输出疾病似乎是这样的:

      Approved (0200) | Approved Off (0220) | Cancel | Total | Time-outs | Disponibility (%)
July | 35                   15                   12      62       0            100.00
.
.
.

编辑: 它只是我查询中的一个表。

  Table Message:
DateMsgIncome date,
DateMsgSent date,
CodMsgIncome varchar(4),
DescMsgIncome varchar(4),
CodMsgAnswer int.

欢迎任何建议。 提前谢谢。

1 个答案:

答案 0 :(得分:2)

我通过代码格式化程序运行您的查询以帮助清理它。我也改变了变量声明,因为你似乎不明白我在说什么。对于记录,你编码的方式可能在一天的最后几毫秒内遗漏了一些行。

我更改了DATEDIFF函数以使用拼出的日期部分名称,因为它太容易使用错误的缩写并弄错了。我还简化了最后一列的计算。如果你将1改为1.0,则不需要投钱。您应该避免对对象名使用保留字,并避免列名中的空格。让前端做这种漂亮的格式化。

我还在使用表提示时添加了很快需要的WITH关键字。 (我建议在使用之前了解NOLOCK的真正含义)。

DECLARE @timTimeout int
    , @iniDate date
    , @endDate date

SET @iniDate = '2014-07-20'              
SET @endDate = '2014-11-25'           
SET @timTimeout = 4000                       

SELECT MONTH(DateMsgIncome) as MyMonthColumn
    , 'Approved (0200)' = ISNULL(SUM(CASE CodMsgIncome WHEN '0200' THEN 1 END), 0)
    , 'Approved Off (0220)' = ISNULL(SUM(CASE CodMsgIncome WHEN '0220' THEN 1 END), 0)
    , 'Cancel (0400)' = ISNULL(SUM(CASE CodMsgIncome WHEN '0400' THEN 1 END), 0)
    , 'Regret (0420)' = ISNULL(SUM(CASE CodMsgIncome WHEN '0420' THEN 1 END), 0)
    , 'TOTAL' = COUNT(*)
    , 'Time-outs' = ISNULL(SUM(CASE WHEN DATEDIFF(MILLISECOND, DateMsgIncome, DateMsgSent) > @timTimeout THEN 1 END), 0)
    , 'Disponibility (%)' = (1.0 - ISNULL(SUM(CASE WHEN DATEDIFF(MILLISECOND, DateMsgIncome, DateMsgSent) > @timTimeout THEN 1 END), 0) / COUNT(*)) * 100
FROM [Message] WITH (NOLOCK) --Ack!!! I wouldn't let this fly on my system due to inconsistencies with this hint unless accuracy is not important (like 

WHERE DateMsgIncome >= @iniDate 
    AND DateMsgIncome < @endDate
    AND CodMsgIncome IN 
    (
        '0200'
        , '0220'
        , '0400'
        , '0420'
        , '0800'
        , '0900'
        , '9080'
        , '9085'
    ) 
    AND DescMsgIncome <> '0220'
GROUP BY MONTH(DateMsgIncome)