如您所见,这很糟糕。有什么选择吗?我尝试在 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 确实是一个浮点数,因此某些列出的解决方案对我的用例无效,因为将值排除在间隔之外。
教训:
如果可能且值得,在 case 表达式中寻找模式以减少它
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
感谢大家,我很难选择一个可以接受的答案,因为很多人都涵盖了问题的不同部分(我当时认为这是一个简单的问题,答案很简单:-),很抱歉造成混淆)。