Como puede ver, esto apesta a lo grande. ¿Alguna alternativa? Intenté usar el alias de columna en el grupo por cláusula inútilmente.Simplificación (aliasing) de sentencias T-SQL CASE. Cualquier mejora posible?
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
EDIT: Realmente quería preguntarle cómo tener una fuente de caso único, pero el caso modificaciones son bienvenidos todos modos (aunque menos útil porque los intervalos probablemente serán modificados y podrían incluso ser generados de forma automática).
Como ha sido considerado por algunas personas, callDuration es de hecho una flotación, por lo que algunas soluciones enumeradas no son válidas para mi caso de uso, al dejar valores fuera de los intervalos.
Lecciones:
buscar patrones en la expresión caso para reducir, si es posible y vale la pena
case when callDuration > 0 AND callDuration < 30 then 1 when callDuration > 600 then 12 else floor(callDuration/60) + 2 end end as duration
utilizar vistas en línea para tener una sola fuente del caso
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
O use las expresiones comunes de la tabla
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
O utilizar una función definida por el usuario (sin ejemplo hasta ahora :-))
O utilizar una tabla de consulta y una unión
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
Gracias a todos y Me está resultando muy difícil elegir una respuesta aceptada, ya que cubrimos diferentes partes de la pregunta (y estaba allí pensando que era una pregunta simple con una respuesta directa :-), disculpe la confusión).
si la pregunta es "¿cómo puedo alias de una expresión compleja para que pueda hacer referencia a ella en una cláusula GROUP BY", un enfoque consiste en utilizar una vista en línea (véase mi respuesta), o una definición de vista almacena en la base de datos). la _otra_ pregunta (todos los demás parecen estar respondiendo) es "cómo simplifico esta expresión en particular", también hay varios enfoques para eso. – spencer7593
@vinko: actualicé mi respuesta para incluir una función definida por el usuario de ejemplo (solo una función escalar para reemplazar la expresión en línea). una función con valores de tabla podría usarse para devolver una tabla de búsqueda ...ese es un enfoque viable también. TENGA CUIDADO con las brechas y superposiciones utilizando tablas de búsqueda y condiciones de combinación (la posibilidad de que las filas se descarten y/o dupliquen). Considere lo que se debe PROBAR frente a la necesidad de flexibilidad. (En mi experiencia, se requiere más esfuerzo para probar el código que para escribir el código). – spencer7593
@ vinko: TAMBIÉN considere especificar cada valor de "punto de interrupción" solo una vez (utilice solo un límite y la garantía de un retorno anticipado cuando se presente una condición está satisfecho.) Deduzco la especificación de que cada callDuration (> 0) debe caer en un depósito y no perderse en un espacio entre dos cubos. – spencer7593