Може да сте запознати с 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 таблица (в този случай само един ред).