wake-up-neo.com

Wie kann ich mehrere Spalten innerhalb eines CASE WEN auf SQL Server auswählen?

Ich habe diese Seite ausgiebig durchsucht, kann aber keine Lösung finden.

Hier ist das Beispiel meiner Anfrage:

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)

natürlich lasse ich viele Fragen aus, ich wollte nur sehen, ob es möglich ist.

Ich weiß, ich könnte den "CASE" wahrscheinlich zweimal machen, dachte aber, ich würde fragen ...

24
Joshua

Das Problem ist, dass die CASE-Anweisung nicht so funktioniert, wie Sie es verwenden möchten. Sie können es nur verwenden, um den Wert eines Feldes in einer Abfrage zu ändern. Wenn ich verstehe, was Sie zu tun versuchen, benötigen Sie möglicherweise Folgendes:

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
28
Josh Anderson

Nein, CASE ist eine Funktion und kann nur einen einzelnen Wert zurückgeben. Ich denke, Sie müssen Ihre CASE-Logik duplizieren.

Die andere Option wäre, die gesamte Abfrage mit einer IF zu umschließen und zwei separate Abfragen zur Rückgabe von Ergebnissen zu haben. Ohne den Rest der Abfrage zu sehen, ist es schwer zu sagen, ob dies für Sie funktionieren würde.

13
Pete McKinney

"Case" kann nur einen einzelnen Wert zurückgeben, aber Sie können einen komplexen Typ verwenden:

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

Eigentlich kannst du es schaffen.

Allerdings sollte jemand beachten, dass das Wiederholen der CASE-Anweisungen nicht so schlecht ist, wie es scheint. Der Abfrageoptimierer von SQL Server ist intelligent genug, um die Variable CASE nicht zweimal auszuführen, sodass Sie dadurch keinen Performance-Treffer erzielen. 

Darüber hinaus verwendet jemand möglicherweise die folgende Logik, um das CASE nicht zu wiederholen (wenn es Ihnen passt.)

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

Dadurch werden die Werte (1, 2, 3) für jeden Datensatz in der Tabelle T1 eingefügt. Dies verwendet ein Trennzeichen '%', um die zusammengeführten Spalten zu teilen. Sie können je nach Ihren Anforderungen eine eigene Split-Funktion schreiben (z. B. zur Verarbeitung von Null-Datensätzen oder zur Verwendung komplexer Trennzeichen für varchar-Felder usw.). Die Hauptlogik besteht jedoch darin, dass Sie die CASE-Anweisung verknüpfen und aus der Ergebnismenge des Joins mit einer Split-Logik auswählen.

0
sotn