正如你所看到的,这很浪费时间。有什么替代方案吗?我尝试在 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
when callDuration > 0 AND callDuration < 30 then 1
when callDuration > 600 then 12
else floor(callDuration/60) + 2 end
end as duration
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/