Một cái gì đó như thế này sẽ hoạt động trong MySQL:
SELECT a.*
FROM (
SELECT ... FROM ... ORDER BY ...
) a
UNION ALL
SELECT b.*
FROM (
SELECT ... FROM ... ORDER BY ...
) b
để trả về các hàng theo thứ tự mà chúng tôi muốn chúng được trả lại. tức là MySQL dường như tôn trọng ORDER BY
mệnh đề bên trong dạng xem nội tuyến.
Tuy nhiên, không có ORDER BY
mệnh đề trên truy vấn ngoài cùng, thứ tự các hàng được trả về là không đảm bảo.
Nếu chúng ta cần các hàng được trả về trong một trình tự cụ thể, chúng ta có thể bao gồm ORDER BY
trên truy vấn ngoài cùng. Trong nhiều trường hợp sử dụng, chúng ta chỉ có thể sử dụng ORDER BY
trên truy vấn ngoài cùng để đáp ứng kết quả.
Nhưng khi chúng ta gặp trường hợp sử dụng trong đó chúng ta cần tất cả các hàng từ truy vấn đầu tiên được trả về trước tất cả các hàng từ truy vấn thứ hai, một tùy chọn là bao gồm một cột phân biệt bổ sung trong mỗi truy vấn. Ví dụ:thêm ,'a' AS src
trong truy vấn đầu tiên, ,'b' AS src
đến truy vấn thứ hai.
Sau đó, truy vấn ngoài cùng có thể bao gồm ORDER BY src, name
, để đảm bảo chuỗi kết quả.
THEO DÕI
Trong truy vấn ban đầu của bạn, ORDER BY
trong các truy vấn của bạn bị loại bỏ bởi trình tối ưu hóa; vì không có ORDER BY
được áp dụng cho truy vấn bên ngoài, MySQL có thể tự do trả về các hàng theo bất kỳ thứ tự nào nó muốn.
"Thủ thuật" trong truy vấn trong câu trả lời của tôi (ở trên) phụ thuộc vào hành vi có thể dành riêng cho một số phiên bản của MySQL.
Trường hợp thử nghiệm:
điền bảng
CREATE TABLE foo2 (id INT PRIMARY KEY, role VARCHAR(20)) ENGINE=InnoDB;
CREATE TABLE foo3 (id INT PRIMARY KEY, role VARCHAR(20)) ENGINE=InnoDB;
INSERT INTO foo2 (id, role) VALUES
(1,'sam'),(2,'frodo'),(3,'aragorn'),(4,'pippin'),(5,'gandalf');
INSERT INTO foo3 (id, role) VALUES
(1,'gimli'),(2,'boromir'),(3,'elron'),(4,'merry'),(5,'legolas');
truy vấn
SELECT a.*
FROM ( SELECT s.id, s.role
FROM foo2 s
ORDER BY s.role
) a
UNION ALL
SELECT b.*
FROM ( SELECT t.id, t.role
FROM foo3 t
ORDER BY t.role
) b
tập kết quả được trả về
id role
------ ---------
3 aragorn
2 frodo
5 gandalf
4 pippin
1 sam
2 boromir
3 elron
1 gimli
5 legolas
4 merry
Các hàng từ foo2
được trả về "theo thứ tự", theo sau là các hàng từ foo3
, một lần nữa, "theo thứ tự".
Lưu ý (một lần nữa) rằng hành vi này là KHÔNG đảm bảo. (Hành vi mà chúng tôi quan sát được là một tác dụng phụ của cách MySQL xử lý các chế độ xem nội tuyến (bảng dẫn xuất). Hành vi này có thể khác trong các phiên bản sau 5.5.)
Nếu bạn cần các hàng được trả về theo một thứ tự cụ thể, thì hãy chỉ định một ORDER BY
mệnh đề cho truy vấn ngoài cùng. Và thứ tự đó sẽ áp dụng cho toàn bộ tập kết quả.
Như tôi đã đề cập trước đó, nếu tôi cần các hàng từ truy vấn đầu tiên trước, sau đó là truy vấn thứ hai, tôi sẽ bao gồm cột "dấu phân biệt" trong mỗi truy vấn và sau đó bao gồm cột "dấu phân biệt" trong mệnh đề ORDER BY. Tôi cũng sẽ loại bỏ các chế độ xem nội tuyến và làm điều gì đó như sau:
SELECT s.id, s.role, 's' AS src
FROM foo2 s
UNION ALL
SELECT t.id, t.role, 't' AS src
FROM foo3 t
ORDER BY src, role