2014-10-24 16 views
7

Ich versuche gerade jetzt die folgende Abfrage aus:ALL vs ANY Auswertung in SQL Server

SELECT DISTINCT code, 
       CASE 
        WHEN id = ANY (SELECT DISTINCT u.id 
           FROM unit u 
             LEFT JOIN unit_const uc 
               ON u.id = uc.hid 
           WHERE u.property = 502 
             AND type = 'Acq') THEN 1 
        ELSE 0 
       END      AS Case_Eval, 
       (SELECT DISTINCT u.id 
       FROM unit u 
         LEFT JOIN unit_const uc 
           ON u.id = uc.hid 
       WHERE u.property = 502 
         AND type = 'Acq') AS Evaluation 
FROM unit 
WHERE property = 502 

, die richtig unter Resultat ergibt:

+---------------------------------------+ 
| Code  Case_Eval Evaluation  | 
+---------------------------------------+ 
| TP2_U1  0   NULL   | 
| TP2_U2  0   NULL   | 
| TP2_U3  0   NULL   | 
| TP2_U4  0   NULL   | 
+---------------------------------------+ 

Aber wenn ich wechsle ANY-ALL dann wird die CASE Anweisung ausgewertet 1.

+---------------------------------------+ 
| Code  Case_Eval Evaluation  | 
+---------------------------------------+ 
| TP2_U1  1   NULL   | 
| TP2_U2  1   NULL   | 
| TP2_U3  1   NULL   | 
| TP2_U4  1   NULL   | 
+---------------------------------------+ 

Aber wie y Sie können die SELECT-Anweisung sehen, die immer den zu vergleichenden Wert in CASENULL zurückgibt.

Wie kann die CASE-Anweisung dies als wahr bewerten? Die Einheit ID ist nicht NULL (sie sind 601, 602, 603 und 604 für die 4 Einheiten), also wie im Vergleich zu ALL(NULL) Ergebnisse in wahr ist?

Gibt es etwas inkorrekt in meinem Verständnis?

Gemäß ALL documentation wertet es einen Skalarwert zu einer Liste von Werten aus.

Und es gibt true zurück, wenn.

"TRUE zurück, wenn der angegebenen Vergleich für alle Paare TRUE (scalar_expression, x), wenn x ein Wert in dem Einzelspaltensatz ist, andernfalls FALSE zurück "

Wie kann Paar (601, NULL) True bewerten?

+0

+1 für die Einführung einiger Syntax ich nie realisiert in T-SQL! – gvee

Antwort

3
SELECT DISTINCT u.id 
FROM unit u 
     LEFT JOIN unit_const uc 
     ON u.id = uc.hid 
WHERE u.property = 502 
     AND type = 'Acq' 

Die obige Anweisung muss null Zeilen zurückgeben. Nicht null. Eine Unterabfrage, die null Zeilen zurückgibt, erhält einen Wert von NULL, wenn sie skalar verwendet wird (wie bei Ihrer Spalte "Auswertung"), aber die Unterabfrage selbst gibt das nicht zurück.

Der SQL-Standard definiert ein anderes Verhalten für ALL und ANY (AKA SOME), wenn es um den Vergleich mit leeren Sätzen kommt.

Für ALL der Vergleich ausgewertet true

If T is empty or if the implied <comparison predicate> is true for every row RT 
in T, then "R <comp op> <all> T" is true. 

Dies ist pro klassischen Logik, wo die Aussagen und „alle Handys im Raum ausgeschaltet“ „alle Handys im Raum eingeschaltet“ sind beide gelten als wahr (though vacuously) wenn das Zimmer keine Handys hat.

Für Any/Some muss mindestens ein Paar vorhanden sein, das tatsächlich übereinstimmt.

Das relevante Bit des SQL-Standards dafür ist unten.

If T is empty or if the implied <comparison predicate> is false for every row RT 
in T, then "R <comp op> <some> T" is false. 
+0

Aber wie kann eine leere Menge im Vergleich zu einer ganzen Zahl als wahr bewertet werden? –

+0

Der Wert, den Sie vergleichen, stimmt mit allen Mitgliedern des Satzes überein, wenn dieser Satz leer ist. –

+0

Ich kann immer noch nicht verstehen, warum '601 = NULL' TRUE ist und eine 1 zurückgibt.Aber 'FALL WÄHLEN, WENN 1 = NULL DANN 1 ELSE 0 ENDE' wird eine 0 zurückgeben. –