Du er måske bekendt med ALL
mulighed i SQL Server. Måske har du brugt det sammen med UNION
operatør for at inkludere eventuelle dubletter, der kan returneres i resultatsættet.
Men vidste du, at ALL
kan også bruges i to andre sammenhænge?
ALL
kan bruges i følgende tre sammenhænge:
- Som argument for
SELECT
klausul. - Som et argument til
UNION
klausul. - Som en logisk operator, når man sammenligner en skalær værdi med et enkelt-kolonne sæt værdier.
Eksempler på hver af disse sammenhænge følger.
ALL
i SELECT
Klausul
Når det bruges sammen med SELECT
klausul, ALL
angiver, at duplikerede værdier returneres i resultatsættet.
Du bruger sandsynligvis allerede dette implicit uden selv at vide det.
I T-SQL er syntaksen for SELECT
klausul lyder sådan her:
SELECT [ ALL | DISTINCT ]
[ TOP ( expression ) [ PERCENT ] [ WITH TIES ] ]
<select_list>
<select_list> ::=
{
*
| { table_name | view_name | table_alias }.*
| {
[ { table_name | view_name | table_alias }. ]
{ column_name | $IDENTITY | $ROWGUID }
| udt_column_name [ { . | :: } { { property_name | field_name }
| method_name ( argument [ ,...n] ) } ]
| expression
[ [ AS ] column_alias ]
}
| column_alias = expression
} [ ,...n ]
Den del, der går [ ALL | DISTINCT ]
betyder, at du får et valg mellem ALL
og DISTINCT
.
De firkantede parenteser betyder, at denne del er valgfri.
ALL
angiver, at dublerede rækker kan vises i resultatsættet.DISTINCT
angiver, at kun unikke rækker kan vises i resultatsættet.
ALL
er standardværdien, så hvis du ikke angiver ALL
eller DISTINCT
, ALL
bruges.
Eksempel
Så de følgende to udsagn er ækvivalente:
SELECT DogName
FROM Dogs;
SELECT ALL DogName
FROM Dogs;
Eksempelresultat:
+-----------+ | DogName | |-----------| | Fetch | | Fluffy | | Wag | | Fetch | +-----------+ (4 rows affected) +-----------+ | DogName | |-----------| | Fetch | | Fluffy | | Wag | | Fetch | +-----------+ (4 rows affected)
Begge resultater viser, at der er to hunde med navnet "Fetch".
Hvis vi bytter ALL
argument for DISTINCT
, vil kun én række blive returneret for "Hent". Dette er fordi DISTINCT
fjerner alle duplikerede værdier fra resultatsættet.
SELECT DISTINCT DogName
FROM Dogs;
Eksempelresultat:
+-----------+ | DogName | |-----------| | Fetch | | Fluffy | | Wag | +-----------+ (3 rows affected)
ALL
i UNION
Klausul
ALL
gør det samme, når det bruges sammen med UNION
klausul. Det specificerer, at duplikerede værdier returneres i resultatsættet.
Men selvfølgelig, UNION
er en anden klausul end SELECT
, så konteksten er lidt anderledes.
UNION
klausul sammenkæder resultaterne af to forespørgsler til et enkelt resultatsæt. Du kan bruge den med eller uden ALL
argument:
UNION ALL
– Inkluderer dubletter.UNION
– Udelukker dubletter.
Eksempel
Her er et eksempel på brug af UNION ALL
at kombinere to forespørgsler.
Lad os tilføje en tabel kaldet Cats
. Så vi har to tabeller:Dogs
og Cats
Dogs
+---------+-----------+ | DogId | DogName | |---------+-----------| | 1 | Fetch | | 2 | Fluffy | | 3 | Wag | | 1002 | Fetch | +---------+-----------+
Cats
+---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 2 | Fluffy | | 3 | Scratch | +---------+-----------+
Lad os nu vælge hunden/kattens navn fra hver tabel og bruge UNION ALL
at kombinere resultaterne fra begge tabeller.
SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats;
Resultat:
+-----------+ | PetName | |-----------| | Fetch | | Fluffy | | Wag | | Fetch | | Meow | | Fluffy | | Scratch | +-----------+ (7 rows affected)
I dette tilfælde returneres syv rækker. Vi kan se, at "Fetch" returneres to gange. Dette skyldes, at der er to hunde ved navn Fetch.
Der er også en kat og en hund med samme navn:Fluffy. (Vi ved, at den anden er en kat, fordi der kun var én hund, der hed Fluffy i det forrige eksempel).
Lad os se, hvad der sker, når jeg fjerner ALL
argument.
SELECT DogName AS PetName
FROM Dogs
UNION
SELECT CatName
FROM Cats;
Resultat:
+-----------+ | PetName | |-----------| | Fetch | | Fluffy | | Meow | | Scratch | | Wag | +-----------+ (5 rows affected)
Denne gang returneres kun fem rækker. Begge dubletter fjernes.
Bemærk, at dette er anderledes end at anvende DISTINCT
til hver enkelt SELECT
udmelding. Hvis vi havde gjort det, ville Fluffy være blevet returneret to gange, fordi ALL
ville kun gælde for SELECT
erklæring om, at det bliver anvendt imod (ikke til de sammenkædede resultater).
Her er et eksempel for at illustrere, hvad jeg mener.
SELECT DISTINCT DogName AS PetName
FROM Dogs
UNION ALL
SELECT DISTINCT CatName
FROM Cats;
Resultat:
+-----------+ | PetName | |-----------| | Fetch | | Fluffy | | Wag | | Fluffy | | Meow | | Scratch | +-----------+ (6 rows affected)
ALL
Operatør
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.
Eksempel
Som en genopfriskning er her vores to borde:
Dogs
+---------+-----------+ | DogId | DogName | |---------+-----------| | 1 | Fetch | | 2 | Fluffy | | 3 | Wag | | 1002 | Fetch | +---------+-----------+
Cats
+---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 2 | Fluffy | | 3 | Scratch | +---------+-----------+
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 | +---------+-----------+
Denne gang får jeg et positivt resultat, fordi alle rækker returneret af underforespørgslen havde en tilsvarende række i Cats
tabel (i dette tilfælde kun én række).