选择case语句的麻烦,需要避免除以0

时间:2013-07-09 07:51:06

标签: sql tsql select case

我正在使用Microsoft SQL Server 2008 R2 (RTM) - 10.50.1617.0 (64-bit)
我有一个表,可以跟踪excel文件中会话期间修改的所有用户,时间和行。我的表(名为: log )原来如下所示:

Opened                  Closed                  Operator        Rows    Mins 
2013-06-26 11:53:58.000 2013-06-26 13:00:55.000 excel-user      225     67
2013-06-26 13:36:32.000 2013-06-26 15:58:25.000 excel-user      473     142
2013-06-26 16:17:34.000 2013-06-26 17:03:08.000 excel-user      181     46

我写了一个简单的查询来计算Rows per Minute。这是我完成工作的查询:

Select opened As 'Opened',
        closed As 'Closed',
        operator As 'Operator', 
        rows As 'Rows', 
        DATEDIFF(MI, opened, closed) As 'Mins',
        Convert( decimal(10,1), rows/Cast(DATEDIFF(MI, opened, closed) as decimal)) as 'Rows/Min'
from log

如果有人打开文件的时间不到一分钟,就会出现问题。然后,分钟数等于0,因此我的当前查询无法给出divide by 0错误 Divide by zero error encountered.
我曾尝试使用查询设计器,但我认为我的案例过于复杂,或者我没有正确地探索查询设计器的可能性。无论如何,我认为实现它的方法是Mins列中的任何数据库条目(行)等于0 时省略计算。我尝试添加where mins <> 0运算符,但只是跳过行并显示不完整的结果=&gt;这是我正在寻找的东西。我已经看过SO和叔叔谷歌然而我仍然无法解决这个问题。我想我得到的想法是我不能在我的案例中应用它。我不会在C#或VB中使用这样简单的语句有任何问题,但SQL不是我的强项,所以我需要你的帮助。
我试过这个查询

SELECT CASE 
    WHEN rows <> 0 
        THEN 
            (
            SELECT 
                opened As 'Opened',
                closed As 'Closed',
                operator As 'Operator', 
                rows As 'Rows', 
                DATEDIFF(MI, opened, closed) As 'Mins',
                Convert( decimal(10,1), rows/Cast(DATEDIFF(MI, opened, closed)as decimal)) as 'Rows/Min'
            )
        ELSE 
            (
            SELECT
                opened As 'Opened',
                closed As 'Closed',
                operator As 'Operator', 
                rows As 'Rows', 
                DATEDIFF(MI, opened, closed) As 'Mins',
                '0' as 'Rows/Min'
            )
    END
FROM log

但它给了我这个错误信息

  

当选择列表中只能指定一个表达式时   EXISTS不引入子查询。   
  我认为这远远超出了我目前对SQL查询的了解,所以我非常感谢您的帮助。一个好的解决方案显然会得到一个复选标记和upvote奖励!

1 个答案:

答案 0 :(得分:2)

CASE语句仅适用于一列,与IF语句不完全相同。

SELECT  opened As 'Opened',
        closed As 'Closed',
        operator As 'Operator', 
        [rows] As 'Rows', 
        DATEDIFF(MI, opened, closed) As 'Mins',
        CASE    WHEN [Rows] <> 0 
                THEN Convert( decimal(10,1), rows/Cast(DATEDIFF(MI, opened, closed) as decimal))
                ELSE 0
        END as 'Rows/Min'
FROM log