Може да сте запознати с ALL
опция в SQL Server. Може би сте го използвали заедно с UNION
оператор, за да включи всички дубликати, които може да бъдат върнати в набора от резултати.
Но знаете ли, че ALL
може да се използва и в два други контекста?
ALL
може да се използва в следните три контекста:
- Като аргумент на
SELECT
клауза. - Като аргумент за
UNION
клауза. - Като логически оператор при сравняване на скаларна стойност с набор от стойности от една колона.
Следват примери за всеки от тези контексти.
ALL
в SELECT
Клауза
Когато се използва с SELECT
клауза, ALL
указва, че в резултатния набор се връщат дублирани стойности.
Вероятно вече използвате това имплицитно, без дори да знаете.
В T-SQL синтаксисът за SELECT
клаузата е така:
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 ]
Частта, която отива [ ALL | DISTINCT ]
означава, че имате избор между ALL
и DISTINCT
.
Квадратните скоби означават, че тази част е незадължителна.
ALL
указва, че дублиращи се редове могат да се появят в набора от резултати.DISTINCT
указва, че само уникални редове могат да се появят в набора от резултати.
ALL
е стойността по подразбиране, така че ако не посочите ALL
или DISTINCT
, ALL
се използва.
Пример
Така че следните две твърдения са еквивалентни:
SELECT DogName
FROM Dogs;
SELECT ALL DogName
FROM Dogs;
Примерен резултат:
+-----------+ | DogName | |-----------| | Fetch | | Fluffy | | Wag | | Fetch | +-----------+ (4 rows affected) +-----------+ | DogName | |-----------| | Fetch | | Fluffy | | Wag | | Fetch | +-----------+ (4 rows affected)
И двата резултата показват, че има две кучета на име „Fetch“.
Ако разменим ALL
аргумент за DISTINCT
, само един ред ще бъде върнат за „Извличане“. Това е така, защото DISTINCT
премахва всички дублиращи се стойности от набора от резултати.
SELECT DISTINCT DogName
FROM Dogs;
Примерен резултат:
+-----------+ | DogName | |-----------| | Fetch | | Fluffy | | Wag | +-----------+ (3 rows affected)
ALL
в UNION
Клауза
ALL
прави същото, когато се използва с UNION
клауза. Той указва, че в резултатния набор се връщат дублиращи се стойности.
Но очевидно, UNION
е различна клауза от SELECT
, така че контекстът е малко по-различен.
UNION
клаузата обединява резултатите от две заявки в един набор от резултати. Можете да го използвате със или без ALL
аргумент:
UNION ALL
– Включва дубликати.UNION
– Изключва дубликати.
Пример
Ето пример за използване на UNION ALL
за комбиниране на две заявки.
Нека добавим таблица, наречена Cats
. Така че имаме две таблици:Dogs
и Cats
Dogs
+---------+-----------+ | DogId | DogName | |---------+-----------| | 1 | Fetch | | 2 | Fluffy | | 3 | Wag | | 1002 | Fetch | +---------+-----------+
Cats
+---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 2 | Fluffy | | 3 | Scratch | +---------+-----------+
Сега нека изберем името на куче/котка от всяка таблица и да използваме UNION ALL
за да комбинирате резултатите от двете таблици.
SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats;
Резултат:
+-----------+ | PetName | |-----------| | Fetch | | Fluffy | | Wag | | Fetch | | Meow | | Fluffy | | Scratch | +-----------+ (7 rows affected)
В този случай се връщат седем реда. Можем да видим, че „Извличане“ се връща два пъти. Това е така, защото има две кучета на име Fetch.
Има също котка и куче със същото име:Fluffy. (Знаем, че другият е котка, защото в предишния пример имаше само едно куче, наречено Fluffy).
Нека видим какво се случва, когато премахна ALL
аргумент.
SELECT DogName AS PetName
FROM Dogs
UNION
SELECT CatName
FROM Cats;
Резултат:
+-----------+ | PetName | |-----------| | Fetch | | Fluffy | | Meow | | Scratch | | Wag | +-----------+ (5 rows affected)
Този път се връщат само пет реда. И двата дубликата се премахват.
Имайте предвид, че това е различно от прилагането на DISTINCT
за всеки отделен SELECT
изявление. Ако бяхме направили това, Fluffy щеше да бъде върнат два пъти, защото ALL
ще се прилага само за SELECT
изявление, срещу което се прилага (не към конкатенираните резултати).
Ето един пример, който да илюстрира какво имам предвид.
SELECT DISTINCT DogName AS PetName
FROM Dogs
UNION ALL
SELECT DISTINCT CatName
FROM Cats;
Резултат:
+-----------+ | PetName | |-----------| | Fetch | | Fluffy | | Wag | | Fluffy | | Meow | | Scratch | +-----------+ (6 rows affected)
ALL
Оператор
ALL
Операторът може да се използва с подзаявка за сравнение на скаларна стойност с набор от стойности от една колона, върнати от подзаявката.
Пример
Като освежаване, ето нашите две таблици:
Dogs
+---------+-----------+ | DogId | DogName | |---------+-----------| | 1 | Fetch | | 2 | Fluffy | | 3 | Wag | | 1002 | Fetch | +---------+-----------+
Cats
+---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 2 | Fluffy | | 3 | Scratch | +---------+-----------+
Сега нека изпълним подзаявка с помощта на 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
таблица (в този случай само един ред).