W SQL Server, ALL
Operator może być używany z podzapytaniem do porównania wartości skalarnej z jednokolumnowym zestawem wartości zwracanych przez podzapytanie.
Prawdą jest również, że SELECT
klauzula i UNION
oba operatory akceptują ALL
argument, chociaż to użycie ma inny cel (pozwala na duplikaty w zestawie wyników).
Poniżej znajdują się przykłady użycia ALL
operator z podzapytaniem.
Przykład
Załóżmy, że mamy dwa stoły; Cats
i Dogs
Cats
+---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 2 | Fluffy | | 3 | Scratch | +---------+-----------+
Dogs
+---------+-----------+ | DogId | DogName | |---------+-----------| | 1 | Fetch | | 2 | Fluffy | | 3 | Wag | +---------+-----------+
Teraz uruchommy podzapytanie za pomocą ALL
operatora.
SELECT
CatId,
CatName
FROM Cats c
WHERE c.CatName = ALL (SELECT DogName FROM Dogs);
Wynik:
(0 rows affected)
W tym przypadku nie zostały zwrócone żadne wiersze. Dzieje się tak, ponieważ ALL
wymaga wyrażenia skalarnego do pozytywnego porównania z każdym wartość zwracana przez podzapytanie.
W tym przypadku podzapytanie było tak szerokie, że wszystkie wiersze z Dogs
tabela została zwrócona. Wymagałoby to, aby każdy pies miał co najmniej jednego odpowiadającego kota o tym samym imieniu.
Zmieńmy nieco podzapytanie.
SELECT
CatId,
CatName
FROM Cats c
WHERE c.CatName = ALL (
SELECT DogName FROM Dogs
WHERE DogId = 2
);
Wynik:
+---------+-----------+ | CatId | CatName | |---------+-----------| | 2 | Fluffy | +---------+-----------+
W tym przypadku otrzymuję wynik pozytywny, ponieważ wszystkie wiersze zwrócone przez podzapytanie miały odpowiedni wiersz w Cats
tabela (choć tylko jeden wiersz).
Zwróć przeciwieństwo
Możemy użyć dowolnego operatora porównania z ALL
. Możemy więc zmodyfikować poprzednie przykłady, aby zwrócić odwrotny wynik, po prostu zmieniając operator równości (=) na operator nierówny (albo <>
lub inny niż ISO !=
).
SELECT
CatId,
CatName
FROM Cats c
WHERE c.CatName <> ALL (SELECT DogName FROM Dogs);
Wynik:
+---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 3 | Scratch | +---------+-----------+
Dlatego zamiast zwracać wszystkie wiersze, które mają odpowiedni wiersz w podzapytaniu, zwracamy wszystkie wiersze, nie mieć odpowiedni wiersz.
I możemy zrobić to samo z innym przykładem.
SELECT
CatId,
CatName
FROM Cats c
WHERE c.CatName <> ALL (
SELECT DogName FROM Dogs
WHERE DogId = 2
);
Wynik:
+---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 3 | Scratch | +---------+-----------+
Błąd 116?
Jeśli pojawi się błąd 116 podczas używania ALL
, prawdopodobnie dlatego, że wybierasz wiele kolumn w podzapytaniu. ALL
Operator może być używany tylko z podzapytaniami, które mają zestaw wyników składający się z jednej kolumny.
Oto przykład tego, jak możemy spowodować ten błąd.
SELECT
CatId,
CatName
FROM Cats c
WHERE c.CatName = ALL (SELECT DogId, DogName FROM Dogs);
Po prostu dodałem kolumnę do podzapytania.
Jest to częsty błąd podczas używania operatora symboli wieloznacznych do zaznaczania wszystkich kolumn w podzapytaniu.
SELECT
CatId,
CatName
FROM Cats c
WHERE c.CatName = ALL (SELECT * FROM Dogs);
Tak czy inaczej, wynik jest taki sam:
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.