Bạn có thể quen thuộc với ALL
trong SQL Server. Có lẽ bạn đã sử dụng nó cùng với UNION
toán tử để bao gồm bất kỳ bản sao nào có thể được trả về trong tập kết quả.
Nhưng bạn có biết rằng ALL
cũng có thể được sử dụng trong hai ngữ cảnh khác?
ALL
có thể được sử dụng trong ba ngữ cảnh sau:
- Làm đối số cho
SELECT
mệnh đề. - Làm đối số cho
UNION
mệnh đề. - Là một toán tử logic khi so sánh một giá trị vô hướng với một tập giá trị một cột.
Sau đây là các ví dụ về từng ngữ cảnh này.
ALL
trong SELECT
Mệnh đề
Khi được sử dụng với SELECT
mệnh đề, ALL
chỉ định rằng các giá trị trùng lặp được trả về trong tập kết quả.
Bạn có thể đã ngầm sử dụng điều này mà không hề biết.
Trong T-SQL, cú pháp cho SELECT
mệnh đề như sau:
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 ]
Phần đi [ ALL | DISTINCT ]
có nghĩa là bạn có một sự lựa chọn giữa ALL
và DISTINCT
.
Dấu ngoặc vuông có nghĩa là phần này là tùy chọn.
-
ALL
chỉ định rằng các hàng trùng lặp có thể xuất hiện trong tập kết quả. -
DISTINCT
chỉ định rằng chỉ các hàng duy nhất mới có thể xuất hiện trong tập kết quả.
ALL
là giá trị mặc định, vì vậy nếu bạn không chỉ định ALL
hoặc DISTINCT
, ALL
được sử dụng.
Ví dụ
Vì vậy, hai câu lệnh sau là tương đương:
SELECT DogName
FROM Dogs;
SELECT ALL DogName
FROM Dogs;
Kết quả ví dụ:
+-----------+ | DogName | |-----------| | Fetch | | Fluffy | | Wag | | Fetch | +-----------+ (4 rows affected) +-----------+ | DogName | |-----------| | Fetch | | Fluffy | | Wag | | Fetch | +-----------+ (4 rows affected)
Cả hai kết quả đều cho thấy có hai con chó tên là “Fetch”.
Nếu chúng ta hoán đổi ALL
đối số cho DISTINCT
, chỉ một hàng sẽ được trả về cho “Tìm nạp”. Điều này là do DISTINCT
xóa mọi giá trị trùng lặp khỏi tập kết quả.
SELECT DISTINCT DogName
FROM Dogs;
Kết quả ví dụ:
+-----------+ | DogName | |-----------| | Fetch | | Fluffy | | Wag | +-----------+ (3 rows affected)
ALL
trong UNION
Mệnh đề
ALL
thực hiện điều tương tự khi được sử dụng với UNION
mệnh đề. Nó chỉ định rằng các giá trị trùng lặp được trả về trong tập kết quả.
Nhưng rõ ràng, UNION
là một mệnh đề khác với SELECT
, vì vậy bối cảnh hơi khác một chút.
UNION
mệnh đề nối kết quả của hai truy vấn thành một tập kết quả duy nhất. Bạn có thể sử dụng nó có hoặc không có ALL
đối số:
-
UNION ALL
- Bao gồm các bản sao. -
UNION
- Loại trừ các bản sao.
Ví dụ
Đây là một ví dụ về việc sử dụng UNION ALL
để kết hợp hai truy vấn.
Hãy thêm một bảng có tên là Cats
. Vì vậy, chúng tôi có hai bảng:Dogs
và Cats
Dogs
+---------+-----------+ | DogId | DogName | |---------+-----------| | 1 | Fetch | | 2 | Fluffy | | 3 | Wag | | 1002 | Fetch | +---------+-----------+
Cats
+---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 2 | Fluffy | | 3 | Scratch | +---------+-----------+
Bây giờ, hãy chọn tên chó / mèo từ mỗi bảng và sử dụng UNION ALL
để kết hợp các kết quả từ cả hai bảng.
SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats;
Kết quả:
+-----------+ | PetName | |-----------| | Fetch | | Fluffy | | Wag | | Fetch | | Meow | | Fluffy | | Scratch | +-----------+ (7 rows affected)
Trong trường hợp này, bảy hàng được trả về. Chúng ta có thể thấy rằng “Tìm nạp” được trả về hai lần. Điều này là do có hai con chó tên là Fetch.
Ngoài ra còn có một con mèo và một con chó cùng tên:Fluffy. (Chúng tôi biết con kia là mèo vì chỉ có một con chó tên là Fluffy trong ví dụ trước).
Hãy xem điều gì sẽ xảy ra khi tôi xóa ALL
đối số.
SELECT DogName AS PetName
FROM Dogs
UNION
SELECT CatName
FROM Cats;
Kết quả:
+-----------+ | PetName | |-----------| | Fetch | | Fluffy | | Meow | | Scratch | | Wag | +-----------+ (5 rows affected)
Lần này chỉ có năm hàng được trả lại. Cả hai bản sao đều bị xóa.
Lưu ý rằng điều này khác với việc áp dụng DISTINCT
cho từng SELECT
riêng lẻ tuyên bố. Nếu chúng tôi làm điều đó, Fluffy sẽ được trả lại hai lần, vì ALL
sẽ chỉ áp dụng cho SELECT
tuyên bố rằng nó đang được áp dụng chống lại (không phải cho các kết quả được nối).
Đây là một ví dụ để minh họa ý tôi muốn nói.
SELECT DISTINCT DogName AS PetName
FROM Dogs
UNION ALL
SELECT DISTINCT CatName
FROM Cats;
Kết quả:
+-----------+ | PetName | |-----------| | Fetch | | Fluffy | | Wag | | Fluffy | | Meow | | Scratch | +-----------+ (6 rows affected)
ALL
Nhà điều hành
ALL
toán tử có thể được sử dụng với một truy vấn con để so sánh một giá trị vô hướng với một tập hợp giá trị cột đơn được trả về bởi truy vấn con.
Ví dụ
Dưới đây là hai bảng của chúng tôi:
Dogs
+---------+-----------+ | DogId | DogName | |---------+-----------| | 1 | Fetch | | 2 | Fluffy | | 3 | Wag | | 1002 | Fetch | +---------+-----------+
Cats
+---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 2 | Fluffy | | 3 | Scratch | +---------+-----------+
Bây giờ, hãy chạy một truy vấn con bằng ALL
nhà điều hành.
SELECT
CatId,
CatName
FROM Cats c
WHERE c.CatName = ALL (SELECT DogName FROM Dogs);
Kết quả:
(0 rows affected)
Trong trường hợp này, không có hàng nào được trả lại. Điều này là do ALL
yêu cầu biểu thức vô hướng để so sánh tích cực với mọi giá trị được trả về bởi truy vấn con.
Trong trường hợp này, truy vấn con quá rộng đến mức tất cả các hàng từ Dogs
bảng đã được trả lại. Điều này yêu cầu mỗi con chó phải có ít nhất một con mèo tương ứng có cùng tên.
Hãy thay đổi truy vấn con một chút.
SELECT
CatId,
CatName
FROM Cats c
WHERE c.CatName = ALL (
SELECT DogName FROM Dogs
WHERE DogId = 2
);
Kết quả:
+---------+-----------+ | CatId | CatName | |---------+-----------| | 2 | Fluffy | +---------+-----------+
Lần này, tôi nhận được kết quả dương tính, vì tất cả các hàng được trả về bởi truy vấn con đều có một hàng tương ứng trong Cats
bảng (trong trường hợp này, chỉ một hàng).