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 ...

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top