В SQL Server, ALL
Операторът може да се използва с подзаявка за сравнение на скаларна стойност с набор от стойности от една колона, върнати от подзаявката.
Също така е вярно, че SELECT
клауза и UNION
и двата оператора приемат ALL
аргумент, въпреки че тази употреба има различна цел (позволява дублиране в набора от резултати).
По-долу са дадени примери за използване на ALL
оператор с подзаявка.
Пример
Да приемем, че имаме две таблици; Cats
и Dogs
Cats
+---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 2 | Fluffy | | 3 | Scratch | +---------+-----------+
Dogs
+---------+-----------+ | DogId | DogName | |---------+-----------| | 1 | Fetch | | 2 | Fluffy | | 3 | Wag | +---------+-----------+
Сега нека изпълним подзаявка с помощта на ALL
оператор.
SELECT
CatId,
CatName
FROM Cats c
WHERE c.CatName = ALL (SELECT DogName FROM Dogs);
Резултат:
(0 rows affected)
В този случай не бяха върнати редове. Това е така, защото ALL
изисква скаларният израз да се сравнява положително с всеки стойност, която се връща от подзаявката.
В този случай подзаявката беше толкова широка, че всички редове от Dogs
масата беше върната. Това ще изисква всяко куче да има поне една съответстваща котка със същото име.
Нека променим леко подзаявката.
SELECT
CatId,
CatName
FROM Cats c
WHERE c.CatName = ALL (
SELECT DogName FROM Dogs
WHERE DogId = 2
);
Резултат:
+---------+-----------+ | CatId | CatName | |---------+-----------| | 2 | Fluffy | +---------+-----------+
В този случай получавам положителен резултат, тъй като всички редове, върнати от подзаявката, имат съответен ред в Cats
таблица (макар и само един ред).
Върнете обратното
Можем да използваме всеки оператор за сравнение с ALL
. Така че бихме могли да модифицираме предишните примери, за да върнем обратния резултат, просто като променим оператора за равенство (=) на оператор не е равно на (или <>
или не ISO стандарт !=
).
SELECT
CatId,
CatName
FROM Cats c
WHERE c.CatName <> ALL (SELECT DogName FROM Dogs);
Резултат:
+---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 3 | Scratch | +---------+-----------+
Така че вместо да връщаме всички редове, които имат съответен ред в подзаявката, ние връщаме всички редове, които не имат съответен ред.
И можем да направим същото с другия пример.
SELECT
CatId,
CatName
FROM Cats c
WHERE c.CatName <> ALL (
SELECT DogName FROM Dogs
WHERE DogId = 2
);
Резултат:
+---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 3 | Scratch | +---------+-----------+
Грешка 116?
Ако получите грешка 116, когато използвате ALL
, вероятно защото избирате няколко колони в подзаявката си. ALL
операторът може да се използва само с подзаявки, които имат набор от резултати от една колона.
Ето пример за това как можем да причиним тази грешка.
SELECT
CatId,
CatName
FROM Cats c
WHERE c.CatName = ALL (SELECT DogId, DogName FROM Dogs);
Просто добавих колона към подзаявката.
Това е често срещана грешка, когато използвате оператора за заместващи знаци, за да изберете всички колони в подзаявката.
SELECT
CatId,
CatName
FROM Cats c
WHERE c.CatName = ALL (SELECT * FROM Dogs);
Така или иначе резултатът е същият:
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.