sql-server - 简化(别名)T-SQL CASE 语句。有什么改进的可能吗?

标签 sql-server tsql case

正如你所看到的,这很浪费时间。有什么替代方案吗?我尝试在 group by 子句中使用列别名无济于事。

select count(callid) ,
case
        when callDuration > 0 and callDuration < 30 then 1
        when callDuration >= 30 and callDuration < 60 then 2
        when callDuration >= 60 and callDuration < 120 then 3
        when callDuration >= 120 and callDuration < 180 then 4
        when callDuration >= 180 and callDuration < 240 then 5
        when callDuration >= 240 and callDuration < 300 then 6
        when callDuration >= 300 and callDuration < 360 then 7
        when callDuration >= 360 and callDuration < 420 then 8
        when callDuration >= 420 and callDuration < 480 then 9
        when callDuration >= 480 and callDuration < 540 then 10
        when callDuration >= 540 and callDuration < 600 then 11
        when callDuration >= 600 then 12
end as duration
from callmetatbl
where programid = 1001 and callDuration > 0
group by case
        when callDuration > 0 and callDuration < 30 then 1
        when callDuration >= 30 and callDuration < 60 then 2
        when callDuration >= 60 and callDuration < 120 then 3
        when callDuration >= 120 and callDuration < 180 then 4
        when callDuration >= 180 and callDuration < 240 then 5
        when callDuration >= 240 and callDuration < 300 then 6
        when callDuration >= 300 and callDuration < 360 then 7
        when callDuration >= 360 and callDuration < 420 then 8
        when callDuration >= 420 and callDuration < 480 then 9
        when callDuration >= 480 and callDuration < 540 then 10
        when callDuration >= 540 and callDuration < 600 then 11
        when callDuration >= 600 then 12
end

编辑:
我真的想询问如何拥有单个案例源,但无论如何都欢迎修改案例(尽管不太有用,因为间隔可能会被修改甚至可能会自动生成)。

正如某些人所考虑的那样, callDuration 确实是一个浮点数,因此通过将值排除在间隔之外,某些列出的解决方案对我的用例无效。

类(class):
  • 在 case 表达式中寻找模式以尽可能减少它并且值得
     case
        when callDuration > 0 AND callDuration < 30 then 1
        when callDuration > 600 then 12
        else floor(callDuration/60) + 2  end
     end as duration
    
  • 使用内联 View 获得案例的单一来源
    select count(d.callid), d.duration
    from (   
       select callid
            , case
               when callDuration > 0 AND callDuration < 30 then 1
               when callDuration > 600 then 12
               else floor(callDuration/60) + 2  end
              end as duration
        from callmetatbl
        where programid = 1001
              and callDuration > 0
    ) d
    group by d.duration
    
  • 或者使用公用表表达式
       with duration_case as (
          select callid ,
          case
            when callDuration > 0 AND callDuration < 30 then 1
            when callDuration > 600 then 12
            else floor(callDuration/60) + 2  end
          end as duration
       from callmetatbl
       where programid = 1001 and callDuration > 0 )
        select count(callid), duration
        from duration_case
        group by duration
    
  • 或者使用用户定义的函数(目前没有示例:-))
  • 或者使用查找表和连接
    DECLARE @t TABLE(durationFrom float, durationTo float, result INT)
    --populate table with values so the query works
    select count(callid) , COALESCE(t.result, 12)
    from callmetatbl JOIN @t AS t ON callDuration >= t.durationFrom 
    AND callDuration < t.durationTo 
    where programid = 1001 and callDuration > 0
    

  • 感谢大家,我很难选择一个可以接受的答案,因为许多人涵盖了问题的不同部分(我当时认为这是一个简单的问题,答案很简单:-),抱歉造成困惑)。

    最佳答案

    您是否有任何理由不使用 between ? case 语句本身看起来还不错。如果你真的讨厌它,你可以把所有这些都扔到一张 table 上并映射出来。

    Durations
    ------------------
    low   high   value
    0     30     1
    31    60     2
    

    等等...
    (SELECT value FROM Durations WHERE callDuration BETWEEN low AND high) as Duration
    

    编辑:或者,在使用浮点数和 between 的情况下变得麻烦。
    (SELECT value FROM Durations WHERE callDuration >= low AND callDuration <= high) as Duration
    

    关于sql-server - 简化(别名)T-SQL CASE 语句。有什么改进的可能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/951836/

    相关文章:

    class - 向 Scala 案例类添加一个字段?

    java - Pervasive 8 中的案例陈述

    sql-server - SQL Server - 递归计算列

    sql-server - 审计 SQL Server 中的两个不同表

    sql - 如何完全删除身份

    sql - 为什么关系在 SQL 实现中很重要?

    sql - 在 Where 子句中使用 Case 语句(带专栏)

    sql-server - 如何从 SSIS 中的 SQL 日期时间值中提取日期?

    sql-server - 访问 INFORMATION_SCHEMA 需要什么权限?

    sql - 如何在存储过程中选择插入的值?