Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Spiegazione dell'operatore ALL di SQL Server

In SQL Server, il ALL può essere utilizzato con una sottoquery per confrontare un valore scalare con un insieme di valori a colonna singola restituito dalla sottoquery.

È anche vero che il SELECT clausola e UNION entrambi accettano un ALL argomento, sebbene questo utilizzo abbia uno scopo diverso (consente duplicati nel set di risultati).

Di seguito sono riportati esempi di utilizzo di ALL operatore con una sottoquery.

Esempio

Supponiamo di avere due tabelle; Cats e Dogs

Cats

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

Dogs

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

Ora eseguiamo una sottoquery utilizzando ALL operatore.

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

Risultato:

(0 rows affected)

In questo caso, non sono state restituite righe. Questo perché ALL richiede che l'espressione scalare venga confrontata positivamente con ogni valore restituito dalla sottoquery.

In questo caso, la sottoquery era così ampia che tutte le righe di Dogs la tabella è stata restituita. Ciò richiederebbe che ogni cane avesse almeno un gatto corrispondente con lo stesso nome.

Modifichiamo leggermente la sottoquery.

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

Risultato:

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

In questo caso ottengo un risultato positivo, perché tutte le righe restituite dalla sottoquery avevano una riga corrispondente in Cats tabella (anche se solo una riga).

Restituisci l'opposto

Possiamo utilizzare qualsiasi operatore di confronto con ALL . Quindi potremmo modificare gli esempi precedenti per restituire il risultato opposto, semplicemente cambiando l'operatore uguale (=) in un operatore diverso da (o <> o lo standard non ISO != ).

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

Risultato:

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

Quindi, invece di restituire tutte le righe che hanno una riga corrispondente nella sottoquery, restituiamo tutte le righe che non avere una riga corrispondente.

E possiamo fare la stessa cosa con l'altro esempio.

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

Risultato:

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

Errore 116?

Se ricevi l'errore 116 quando usi ALL , probabilmente è perché stai selezionando più colonne nella tua sottoquery. Il ALL l'operatore può essere utilizzato solo con sottoquery che hanno un set di risultati di una colonna.

Ecco un esempio di come possiamo causare questo errore.

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

Ho semplicemente aggiunto una colonna alla sottoquery.

È un errore comune quando si utilizza l'operatore con caratteri jolly per selezionare tutte le colonne nella sottoquery.

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

In ogni caso, il risultato è lo stesso:

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.