2010-01-15 10 views
22

Przeszukałem tę stronę, ale nie mogę znaleźć rozwiązania.Jak mogę WYBRAĆ wiele kolumn w CASE WHEN na serwerze SQL?

Oto przykład mojej kwerendy:

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) 

oczywiście Wyjeżdżam z dużo zapytania, po prostu chciałem zobaczyć, czy jest to możliwe.

wiem, że prawdopodobnie może po prostu zrobić „przypadek” dwa razy, ale zorientowali prosiłbym ...

Dzięki!

+0

Powiązane pytanie, ale NIE duplikat to http://stackoverflow.com/q/13713316/2420536 –

Odpowiedz

26

Problem polega na tym, że instrukcja CASE nie działa w sposób, w jaki próbujesz go użyć. Możesz go użyć tylko do przełączania wartości jednego pola w zapytaniu. Jeśli dobrze rozumiem, co próbujesz zrobić, być może trzeba to:

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 
12

Nie, CASE jest funkcją i może zwrócić tylko jedną wartość. Myślę, że będziesz musiał skopiować swoją logikę CASE.

Inną opcją byłoby zawarcie całego zapytania z IF i mieć dwa oddzielne zapytania do zwracania wyników. Nie widząc reszty zapytania, trudno powiedzieć, czy to by działało dla Ciebie.

1

„przypadek” może zwrócić tylko jedną wartość, ale można użyć typu złożonego:

create type foo as (a int, b text); 
select (case 1 when 1 then (1,'qq')::foo else (2,'ww')::foo end).*; 
+2

Myślę, że jest to możliwe w Postgresie, ale nie w serwerze sql (z którym to pytanie jest oznaczone) – dsz

0

Właściwie można zrobić to.

Chociaż ktoś powinien zauważyć, że powtarzanie instrukcji CASE nie jest takie złe, jak się wydaje. Optymalizator zapytań SQL Server jest wystarczająco inteligentny, aby dwukrotnie nie wykonywać CASE, aby nie uzyskać żadnego wyniku wydajności z tego powodu.

Dodatkowo, ktoś może użyć następującego logiki nie powtórzyć sprawy (jeśli ci pasuje ..)

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 

To spowoduje wstawienie wartości (1, 2, 3) dla każdego rekordu w tabeli T1. Wykorzystuje separator '%' do podziału scalonych kolumn. Możesz napisać własną funkcję podziału w zależności od twoich potrzeb (np. Do obsługi pustych rekordów lub używania złożonego separatora dla pól varchar). Ale główna logika polega na tym, że powinieneś dołączyć do instrukcji CASE i wybrać z zestawu wyników łączenia za pomocą logiki podziału.

Powiązane problemy