Come posso selezionare più colonne all'interno di un caso quando su SQL Server?
-
20-09-2019 - |
Domanda
Ho cercato questo sito ampiamente, ma non riesco a trovare una soluzione.
Ecco l'esempio della mia interrogazione:
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)
Ovviamente sto lasciando fuori un sacco di query, volevo solo vedere se è possibile.
So che probabilmente potuto solo fare il "caso" due volte, ma pensato che vorrei chiedere ...
Soluzione
Il problema è che la dichiarazione CASE
non funziona nel modo in cui si sta cercando di usarlo. È possibile utilizzarla solo per cambiare il valore di un campo in una query. Se ho ben capito quello che stai cercando di fare, potrebbe essere necessario in questo modo:
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
Altri suggerimenti
No, CASE
è una funzione, e può restituire solo un singolo valore. Penso che si sta andando ad avere per duplicare la logica CASE.
L'altra opzione sarebbe quella di avvolgere l'intera query con un IF e hanno due query separate per restituire i risultati. Senza vedere il resto della query, è difficile dire se questo avrebbe funzionato per voi.
"Case" in grado di restituire valore singolo solo, ma è possibile utilizzare tipo complesso:
create type foo as (a int, b text);
select (case 1 when 1 then (1,'qq')::foo else (2,'ww')::foo end).*;
In realtà si può fare.
Anche se, qualcuno dovrebbe notare che ripetere le dichiarazioni CASE
non sono male come sembra. Query Optimizer di SQL Server è abbastanza intelligente per non eseguire la CASE
due volte in modo che non sarà possibile ottenere alcun calo di prestazioni a causa di questo.
Inoltre, qualcuno potrebbe utilizzare la seguente logica di non ripetere il caso (se vi si addice ..)
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
Questo inserirà i valori (1, 2, 3) per ogni record della tabella T1
. Questo utilizza un '%'
delimitatore di dividere le colonne unite. È possibile scrivere la propria funzione divisa a seconda delle esigenze (ad esempio per la gestione di record nulli o utilizzando delimitatore complessa per i campi varchar
etc.). Ma la logica principale è che si dovrebbe aderire alla dichiarazione CASE
e scegliere tra il set di risultati del join con l'utilizzo di una logica di divisione.