Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

SQL Server ALL-Operator erklärt

In SQL Server ist der ALL -Operator kann mit einer Unterabfrage verwendet werden, um einen Skalarwert mit einem einspaltigen Wertesatz zu vergleichen, der von der Unterabfrage zurückgegeben wird.

Es stimmt auch, dass die SELECT -Klausel und UNION Operator akzeptieren beide einen ALL Argument, obwohl diese Verwendung einen anderen Zweck hat (ermöglicht Duplikate in der Ergebnismenge).

Nachfolgend finden Sie Beispiele für die Verwendung von ALL Operator mit einer Unterabfrage.

Beispiel

Angenommen, wir haben zwei Tabellen; Cats und Dogs

Cats

+---------+-----------+
| CatId   | CatName   |
|---------+-----------|
| 1       | Meow      |
| 2       | Fluffy    |
| 3       | Scratch   |
+---------+-----------+

Dogs

+---------+-----------+
| DogId   | DogName   |
|---------+-----------|
| 1       | Fetch     |
| 2       | Fluffy    |
| 3       | Wag       |
+---------+-----------+

Lassen Sie uns nun eine Unterabfrage mit ALL ausführen Betreiber.

SELECT 
    CatId,
    CatName
FROM Cats c 
WHERE c.CatName = ALL (SELECT DogName FROM Dogs);

Ergebnis:

(0 rows affected)

In diesem Fall wurden keine Zeilen zurückgegeben. Das liegt daran, dass ALL erfordert, dass der skalare Ausdruck positiv mit every verglichen werden kann Wert, der von der Unterabfrage zurückgegeben wird.

In diesem Fall war die Unterabfrage so breit angelegt, dass alle Zeilen aus Dogs Tisch wurde zurückgegeben. Dies würde erfordern, dass jeder Hund mindestens eine entsprechende Katze mit demselben Namen hat.

Lassen Sie uns die Unterabfrage etwas ändern.

SELECT 
    CatId,
    CatName
FROM Cats c 
WHERE c.CatName = ALL (
    SELECT DogName FROM Dogs 
    WHERE DogId = 2
    );

Ergebnis:

+---------+-----------+
| CatId   | CatName   |
|---------+-----------|
| 2       | Fluffy    |
+---------+-----------+

In diesem Fall erhalte ich ein positives Ergebnis, da alle von der Unterabfrage zurückgegebenen Zeilen eine entsprechende Zeile in den Cats hatten Tabelle (allerdings nur eine Zeile).

Geben Sie das Gegenteil zurück

Wir können jeden Vergleichsoperator mit ALL verwenden . Wir könnten also die vorherigen Beispiele ändern, um das entgegengesetzte Ergebnis zurückzugeben, indem wir einfach den Gleichheitsoperator (=) in einen Ungleichheitsoperator ändern (entweder <> oder der Nicht-ISO-Standard != ).

SELECT 
    CatId,
    CatName
FROM Cats c 
WHERE c.CatName <> ALL (SELECT DogName FROM Dogs);

Ergebnis:

+---------+-----------+
| CatId   | CatName   |
|---------+-----------|
| 1       | Meow      |
| 3       | Scratch   |
+---------+-----------+

Anstatt also alle Zeilen zurückzugeben, die eine entsprechende Zeile in der Unterabfrage haben, geben wir alle Zeilen zurück, die keine haben eine entsprechende Zeile haben.

Und wir können dasselbe mit dem anderen Beispiel machen.

SELECT 
    CatId,
    CatName
FROM Cats c 
WHERE c.CatName <> ALL (
    SELECT DogName FROM Dogs 
    WHERE DogId = 2
    );

Ergebnis:

+---------+-----------+
| CatId   | CatName   |
|---------+-----------|
| 1       | Meow      |
| 3       | Scratch   |
+---------+-----------+

Fehler 116?

Wenn Sie bei Verwendung von ALL den Fehler 116 erhalten , liegt es wahrscheinlich daran, dass Sie mehrere Spalten in Ihrer Unterabfrage auswählen. Die ALL Der Operator kann nur mit Unterabfragen verwendet werden, die eine Ergebnismenge von einer Spalte haben.

Hier ist ein Beispiel dafür, wie wir diesen Fehler verursachen können.

SELECT 
    CatId,
    CatName
FROM Cats c 
WHERE c.CatName = ALL (SELECT DogId, DogName FROM Dogs);

Ich habe der Unterabfrage einfach eine Spalte hinzugefügt.

Es ist ein häufiger Fehler, wenn der Platzhalteroperator verwendet wird, um alle Spalten in der Unterabfrage auszuwählen.

SELECT 
    CatId,
    CatName
FROM Cats c 
WHERE c.CatName = ALL (SELECT * FROM Dogs);

In beiden Fällen ist das Ergebnis dasselbe:

Msg 116, Level 16, State 1, Line 5
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.