I SQL Server er ALL
operator kan bruges sammen med en underforespørgsel til at sammenligne en skalær værdi med et enkelt-kolonne sæt værdier, der returneres af underforespørgslen.
Det er også rigtigt, at SELECT
klausul og UNION
operatør accepterer begge en ALL
argument, selvom denne brug har et andet formål (tillader dubletter i resultatsættet).
Nedenfor er eksempler på brug af ALL
operatør med en underforespørgsel.
Eksempel
Antag, at vi har to tabeller; Cats
og Dogs
Cats
+---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 2 | Fluffy | | 3 | Scratch | +---------+-----------+
Dogs
+---------+-----------+ | DogId | DogName | |---------+-----------| | 1 | Fetch | | 2 | Fluffy | | 3 | Wag | +---------+-----------+
Lad os nu køre en underforespørgsel ved hjælp af ALL
operatør.
SELECT
CatId,
CatName
FROM Cats c
WHERE c.CatName = ALL (SELECT DogName FROM Dogs);
Resultat:
(0 rows affected)
I dette tilfælde blev ingen rækker returneret. Dette er fordi ALL
kræver, at det skalære udtryk kan sammenlignes positivt med hver værdi, der returneres af underforespørgslen.
I dette tilfælde var underforespørgslen så bred, at alle rækker fra Dogs
bord blev returneret. Dette ville kræve, at hver hund havde mindst én tilsvarende kat med samme navn.
Lad os ændre underforespørgslen lidt.
SELECT
CatId,
CatName
FROM Cats c
WHERE c.CatName = ALL (
SELECT DogName FROM Dogs
WHERE DogId = 2
);
Resultat:
+---------+-----------+ | CatId | CatName | |---------+-----------| | 2 | Fluffy | +---------+-----------+
I dette tilfælde får jeg et positivt resultat, fordi alle rækker returneret af underforespørgslen havde en tilsvarende række i Cats
tabel (omend kun én række).
Genfør det modsatte
Vi kan bruge enhver sammenligningsoperator med ALL
. Så vi kunne ændre de foregående eksempler for at returnere det modsatte resultat, simpelthen ved at ændre lig-operatoren (=) til en ikke lig med-operator (enten <>
eller ikke ISO-standarden !=
).
SELECT
CatId,
CatName
FROM Cats c
WHERE c.CatName <> ALL (SELECT DogName FROM Dogs);
Resultat:
+---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 3 | Scratch | +---------+-----------+
Så i stedet for at returnere alle rækker, der har en tilsvarende række i underforespørgslen, returnerer vi alle rækker, der ikke har en tilsvarende række.
Og vi kan gøre det samme med det andet eksempel.
SELECT
CatId,
CatName
FROM Cats c
WHERE c.CatName <> ALL (
SELECT DogName FROM Dogs
WHERE DogId = 2
);
Resultat:
+---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 3 | Scratch | +---------+-----------+
Fejl 116?
Hvis du får fejl 116, når du bruger ALL
, er det sandsynligvis fordi du vælger flere kolonner i din underforespørgsel. ALL
operator kan kun bruges med underforespørgsler, der har et resultatsæt på én kolonne.
Her er et eksempel på, hvordan vi kan forårsage denne fejl.
SELECT
CatId,
CatName
FROM Cats c
WHERE c.CatName = ALL (SELECT DogId, DogName FROM Dogs);
Jeg tilføjede simpelthen en kolonne til underforespørgslen.
Det er en almindelig fejl, når jokertegnoperatoren bruges til at vælge alle kolonner i underforespørgslen.
SELECT
CatId,
CatName
FROM Cats c
WHERE c.CatName = ALL (SELECT * FROM Dogs);
Uanset hvad, er resultatet det samme:
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.