Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Mệnh đề MySQL UNION

Trong MySQL, UNION mệnh đề kết hợp các kết quả từ nhiều truy vấn thành một tập kết quả duy nhất.

Ví dụ

Giả sử chúng ta có các bảng sau:

SELECT * FROM Teachers;
SELECT * FROM Students;

Kết quả:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         1 | Warren      |
|         2 | Ben         |
|         3 | Cathy       |
|         4 | Cathy       |
|         5 | Bill        |
|         6 | Bill        |
+-----------+-------------+

+-----------+-------------+
| StudentId | StudentName |
+-----------+-------------+
|         1 | Faye        |
|         2 | Jet         |
|         3 | Spike       |
|         4 | Ein         |
|         5 | Warren      |
|         6 | Bill        |
+-----------+-------------+

Chúng tôi có thể chèn UNION mệnh đề giữa hai SELECT đó câu lệnh gửi lại tất cả giáo viên và học sinh:

SELECT TeacherName FROM Teachers
UNION
SELECT StudentName FROM Students;

Kết quả:

+-------------+
| TeacherName |
+-------------+
| Warren      |
| Ben         |
| Cathy       |
| Bill        |
| Faye        |
| Jet         |
| Spike       |
| Ein         |
+-------------+

Tên cột được lấy từ SELECT đầu tiên tuyên bố.

Theo mặc định, UNION mệnh đề áp dụng ngầm một DISTINCT hoạt động. Nói cách khác, nó chỉ trả về các giá trị riêng biệt theo mặc định. Vì vậy, các kết quả trên chỉ chứa một trong số Warren, Cathy và Bill. Điều này là mặc dù thực tế là các bảng kết hợp thực sự chứa hai Warrens, hai Cathys và ba Bills (có hai giáo viên tên là Cathy, một giáo viên và một khách hàng tên là Warren, và hai người tên là Bill, cũng như một học sinh tên là Bill).

Dưới đây là một ví dụ sử dụng rõ ràng DISTINCT mệnh đề:

SELECT TeacherName FROM Teachers
UNION DISTINCT
SELECT StudentName FROM Students;

Kết quả:

+-------------+
| TeacherName |
+-------------+
| Warren      |
| Ben         |
| Cathy       |
| Bill        |
| Faye        |
| Jet         |
| Spike       |
| Ein         |
+-------------+

Vì vậy, chúng tôi nhận được cùng một kết quả mà chúng tôi nhận được mà không có DISTINCT mệnh đề.

Bao gồm các bản sao

Chúng ta có thể sử dụng ALL từ khóa để bao gồm các giá trị trùng lặp trong kết quả:

SELECT TeacherName FROM Teachers
UNION ALL
SELECT StudentName FROM Students;

Kết quả:

+-------------+
| TeacherName |
+-------------+
| Warren      |
| Ben         |
| Cathy       |
| Cathy       |
| Bill        |
| Bill        |
| Faye        |
| Jet         |
| Spike       |
| Ein         |
| Warren      |
| Bill        |
+-------------+

Lần này chúng ta có 12 hàng thay vì 8 hàng như trong ví dụ đầu tiên.

Chúng ta có thể thấy rằng cả hai Cathys đã được trả lại và cả ba Hóa đơn đã được trả lại.

TABLE Tuyên bố

Từ MySQL 8.0.19, chúng ta có thể sử dụng UNION mệnh đề với TABLE tuyên bố.

Đây là một ví dụ:

TABLE Teachers
UNION
TABLE Students;

Kết quả:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         1 | Warren      |
|         2 | Ben         |
|         3 | Cathy       |
|         4 | Cathy       |
|         5 | Bill        |
|         6 | Bill        |
|         1 | Faye        |
|         2 | Jet         |
|         3 | Spike       |
|         4 | Ein         |
|         5 | Warren      |
+-----------+-------------+

Điều đó tương đương với truy vấn sau:

SELECT * FROM Teachers
UNION
SELECT * FROM Students;

Kết quả:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         1 | Warren      |
|         2 | Ben         |
|         3 | Cathy       |
|         4 | Cathy       |
|         5 | Bill        |
|         6 | Bill        |
|         1 | Faye        |
|         2 | Jet         |
|         3 | Spike       |
|         4 | Ein         |
|         5 | Warren      |
+-----------+-------------+

Bạn sẽ nhận thấy rằng những câu lệnh này trả về nhiều hàng hơn trong ví dụ đầu tiên của chúng tôi trước đó. Đó là bởi vì chúng tôi đang chọn tất cả các cột trong bảng, điều này dẫn đến các cột không trùng lặp mà trước đó đã có một cột trùng lặp. Ví dụ:hai giáo viên tên là Bill được trả về ở đây trong khi chỉ có một giáo viên được trả lại trong ví dụ trước đó. Đó là vì TeacherId các cột chứa các giá trị khác nhau, do đó các hàng không trùng lặp.

Sử dụng ORDER BY Mệnh đề trong Truy vấn Liên minh

Chúng ta có thể sử dụng ORDER BY mệnh đề trong mỗi SELECT và / hoặc trên UNION kết hợp truy vấn.

Trong mỗi SELECT Tuyên bố

Khi chúng tôi sử dụng ORDER BY mệnh đề trong SELECT riêng lẻ các câu lệnh trong UNION truy vấn, chúng ta cần bao gồm mỗi SELECT câu lệnh bên trong dấu ngoặc đơn:

(SELECT * FROM Teachers ORDER BY TeacherName ASC LIMIT 2)
UNION
(SELECT * FROM Students ORDER BY StudentName ASC LIMIT 2);

Kết quả:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         2 | Ben         |
|         5 | Bill        |
|         6 | Bill        |
|         4 | Ein         |
+-----------+-------------+

Lưu ý rằng khi chúng tôi làm điều này, nó không thực sự sắp xếp kết quả cho đầu ra. Nó chỉ sắp xếp các kết quả cho mục đích xác định tập hợp con của các hàng đã chọn để truy xuất khi áp dụng LIMIT mệnh đề.

Do đó, sử dụng ORDER BY không có LIMIT mệnh đề không ảnh hưởng đến đầu ra.

Trên Toàn bộ UNION Truy vấn

Chúng tôi cũng có thể sử dụng ORDER BY trên toàn bộ truy vấn, để toàn bộ đầu ra được sắp xếp cùng nhau.

Trong ví dụ này, chúng tôi lấy ví dụ trước đó và sắp xếp các kết quả được kết hợp:

(SELECT * FROM Teachers ORDER BY TeacherName ASC LIMIT 2)
UNION
(SELECT * FROM Students ORDER BY StudentName ASC LIMIT 2)
ORDER BY TeacherName DESC;

Kết quả:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         4 | Ein         |
|         5 | Bill        |
|         6 | Bill        |
|         2 | Ben         |
+-----------+-------------+

Ngay cả khi không sử dụng ORDER BY mệnh đề trong mỗi SELECT câu lệnh, mỗi SELECT câu lệnh vẫn phải nằm trong ngoặc đơn và ORDER BY mệnh đề (hoặc bất kỳ LIMIT nào mệnh đề) phải ở sau mệnh đề cuối cùng.

(SELECT * FROM Teachers)
UNION
(SELECT * FROM Students)
ORDER BY TeacherName ASC;

Kết quả:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         2 | Ben         |
|         5 | Bill        |
|         6 | Bill        |
|         3 | Cathy       |
|         4 | Cathy       |
|         4 | Ein         |
|         1 | Faye        |
|         2 | Jet         |
|         3 | Spike       |
|         1 | Warren      |
|         5 | Warren      |
+-----------+-------------+

Xin lưu ý bạn, việc bỏ qua dấu ngoặc đơn sẽ tạo ra kết quả giống như kết quả có dấu ngoặc đơn:

SELECT * FROM Teachers
UNION
SELECT * FROM Students
ORDER BY TeacherName ASC;

Kết quả:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         2 | Ben         |
|         5 | Bill        |
|         6 | Bill        |
|         3 | Cathy       |
|         4 | Cathy       |
|         4 | Ein         |
|         1 | Faye        |
|         2 | Jet         |
|         3 | Spike       |
|         1 | Warren      |
|         5 | Warren      |
+-----------+-------------+

Lưu ý rằng nếu cột được sắp xếp sử dụng bí danh, thì cột đó phải được tham chiếu bằng bí danh của nó (không phải tên cột).

Ví dụ:

(SELECT TeacherName t FROM Teachers)
UNION
(SELECT StudentName FROM Students)
ORDER BY t ASC;

Kết quả:

+--------+
| t      |
+--------+
| Ben    |
| Bill   |
| Cathy  |
| Ein    |
| Faye   |
| Jet    |
| Spike  |
| Warren |
+--------+

Đây là những gì sẽ xảy ra nếu chúng tôi không sử dụng bí danh:

(SELECT TeacherName t FROM Teachers)
UNION
(SELECT StudentName FROM Students)
ORDER BY TeacherName ASC;

Kết quả:

ERROR 1054 (42S22): Unknown column 'TeacherName' in 'order clause'

Số lượng Cột

Số cột được trả về bởi mỗi SELECT tuyên bố phải giống nhau. Do đó, chúng tôi không thể làm những việc sau:

SELECT TeacherName FROM Teachers
UNION
SELECT StudentId, StudentName FROM Students;

Kết quả:

ERROR 1222 (21000): The used SELECT statements have a different number of columns

Loại dữ liệu

Các cột đã chọn được liệt kê ở các vị trí tương ứng của mỗi SELECT câu lệnh phải có cùng kiểu dữ liệu. Tuy nhiên, nếu không, thì loại và độ dài của các cột trong UNION kết quả có tính đến các giá trị được truy xuất bởi tất cả SELECT tuyên bố.

Đây là những gì sẽ xảy ra nếu chúng tôi cố gắng kết hợp TeacherName với StudentId cột:

SELECT TeacherName FROM Teachers
UNION
SELECT StudentId FROM Students;

Kết quả:

+-------------+
| TeacherName |
+-------------+
| Warren      |
| Ben         |
| Cathy       |
| Bill        |
| 1           |
| 2           |
| 3           |
| 4           |
| 5           |
| 6           |
+-------------+

Một số RDBMS khác sẽ tạo ra lỗi trong trường hợp này, nhưng MySQL quản lý để tạo ra đầu ra mà không có lỗi.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL, cập nhật nhiều bảng với một truy vấn

  2. MySQL trên Azure Performance Benchmark - ScaleGrid so với Cơ sở dữ liệu Azure

  3. Không thể khởi động mùa xuân để tự động tạo giản đồ cơ sở dữ liệu

  4. Cách kiểm tra phiên bản MySQL

  5. Cách cài đặt cơ sở dữ liệu MariaDB trong Debian 10