¿Cómo puedo seleccionar varias columnas dentro de un caso cuando en SQL Server?
-
20-09-2019 - |
Pregunta
He buscado este sitio ampliamente, pero no puedo encontrar una solución.
Aquí está el ejemplo de mi consulta:
SELECT
ActivityID,
Hours = (CASE
WHEN ActivityTypeID <> 2 THEN
FieldName = (Some Aggregate Sub Query),
FieldName2 = (Some other aggregate sub query)
WHEN ActivityTypeID = 2 THEN
FieldName = (Some Aggregate Sub Query with diff result),
FieldName2 = (Some Other Aggregate Sub Query with diff result)
END)
Obviamente estoy dejando una gran cantidad de la consulta, sólo quería ver si es posible.
Sé que probablemente sólo podría hacer el "caso" dos veces, pero pensé que le pregunte ...
Solución
El problema es que la declaración CASE
no funcionará en la forma en que está tratando de usarlo. Sólo se puede utilizar para cambiar el valor de un campo en una consulta. Si entiendo lo que estás tratando de hacer, es posible que tenga la siguiente:
SELECT
ActivityID,
FieldName = CASE
WHEN ActivityTypeID <> 2 THEN
(Some Aggregate Sub Query)
ELSE
(Some Aggregate Sub Query with diff result)
END,
FieldName2 = CASE
WHEN ActivityTypeID <> 2 THEN
(Some Aggregate Sub Query)
ELSE
(Some Aggregate Sub Query with diff result)
END
Otros consejos
No, CASE
es una función, y sólo puede devolver un solo valor. Creo que vas a tener que duplicar su lógica CASO.
La otra opción sería la de envolver toda la consulta con un SI y tienen dos consultas separadas para devolver resultados. Sin ver el resto de la consulta, es difícil decir si eso fuera a funcionar para usted.
"Caso" puede devolver un único valor solamente, pero se puede utilizar el tipo de complejo:
create type foo as (a int, b text);
select (case 1 when 1 then (1,'qq')::foo else (2,'ww')::foo end).*;
En realidad, usted puede hacerlo.
A pesar de que, alguien debe repetir en cuenta que las declaraciones CASE
no están mal como parece. optimizador de consultas de SQL Server es lo suficientemente inteligente como para no ejecutar la CASE
dos veces para que no obtendrá ningún impacto en el rendimiento debido a eso.
Además, alguien podría usar la siguiente lógica para no repetir la caja (si lo que necesite ..)
INSERT INTO dbo.T1
(
Col1,
Col2,
Col3
)
SELECT
1,
SUBSTRING(MyCase.MergedColumns, 0, CHARINDEX('%', MyCase.MergedColumns)),
SUBSTRING(MyCase.MergedColumns, CHARINDEX('%', MyCase.MergedColumns) + 1, LEN(MyCase.MergedColumns) - CHARINDEX('%', MyCase.MergedColumns))
FROM
dbo.T1 t
LEFT OUTER JOIN
(
SELECT CASE WHEN 1 = 1 THEN '2%3' END MergedColumns
) AS MyCase ON 1 = 1
Esto insertará los valores (1, 2, 3) para cada registro en la T1
tabla. Este utiliza un '%'
delimitador para separar las columnas combinadas. Usted puede escribir su propia función de división en función de sus necesidades (por ejemplo, para el manejo de registros nulos o usando delimitador complejo de campos varchar
etc.). Pero la lógica principal es que debe unirse a la declaración CASE
y seleccionar entre el conjunto de resultados de la unión con el uso de una lógica de división.