2010-01-15 14 views
22

Ich habe diese Seite ausführlich gesucht, kann aber keine Lösung finden. HierWie kann ich mehrere Spalten innerhalb eines CASE WHEN auf SQL Server auswählen?

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) 

offensichtlich Ich verlasse eine Menge von der Abfrage aus, ich wollte nur sehen, ob es möglich ist.

Ich weiß, dass ich wahrscheinlich nur könnte die „CASE“ zweimal tun, aber dachte, ich würde fragen ...

Dank!

+0

Verwandte Frage, aber kein Duplikat ist http://stackoverflow.com/q/13713316/2420536 –

Antwort

26

Das Problem ist, dass die CASE Anweisung nicht in der Art funktioniert, wie Sie versuchen, es zu verwenden. Sie können es nur verwenden, um den Wert eines Felds in einer Abfrage zu wechseln. Wenn ich verstehe, was Sie zu tun versuchen, müssen Sie dies:

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

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

Die andere Option wäre, die gesamte Abfrage mit einem IF zu umbrechen und zwei separate Abfragen zu haben, um Ergebnisse zurückzugeben. Ohne den Rest der Abfrage zu sehen, ist es schwer zu sagen, ob das für Sie funktionieren würde.

1

„Fall“ nur einzelnen Wert zurückgeben kann, aber können Sie komplexe Art verwenden:

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

Ich denke, das ist in Postgres möglich, aber nicht sql-Server (die die Frage mit getaggt ist) – dsz

0

Eigentlich können Sie tun es.

Obwohl, jemand sollte beachten, dass die Wiederholung der CASE Aussagen sind nicht schlecht, wie es scheint. Der Abfrageoptimierer von SQL Server ist intelligent genug, um die CASE nicht zweimal auszuführen, sodass Sie dadurch keine Leistungseinbußen erhalten.

Zusätzlich könnte jemand die folgende Logik verwenden, den Fall nicht 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 einfügen (1, 2, 3) für jeden Datensatz in der Tabelle T1. Dies verwendet ein Trennzeichen '%', um die zusammengeführten Spalten zu teilen. Sie können je nach Bedarf eine eigene Split-Funktion schreiben (z. B. für die Behandlung von Nullsätzen oder die Verwendung eines komplexen Trennzeichens für varchar Felder usw.). Aber die Hauptlogik ist, dass Sie die CASE-Anweisung beitreten und aus der Ergebnismenge der Verknüpfung mit einer Split-Logik auswählen sollten.

Verwandte Themen