2013-04-02 29 views
34

Tôi có thể chắc chắn rằng tập hợp kết quả của tập lệnh sau sẽ luôn được sắp xếp như thế này O-R-D-E-R?UNION ALL có đảm bảo thứ tự của tập hợp kết quả

SELECT 'O' 
UNION ALL 
SELECT 'R' 
UNION ALL 
SELECT 'D' 
UNION ALL 
SELECT 'E' 
UNION ALL 
SELECT 'R' 

Đôi khi có thể được chứng minh theo thứ tự khác không?

+8

Tại sao mọi người lại có thể đảm bảo đặt hàng ngoại trừ khi có điều khoản 'ORDER BY'? - Có một cơ hội rõ ràng cho tính song song (nếu có đủ tài nguyên) để tính toán từng tập kết quả song song và phục vụ mỗi hàng kết quả (từ các truy vấn song song) đến máy khách theo thứ tự bất kỳ mà mỗi hàng kết quả riêng lẻ có sẵn. –

+2

@Damien_The_Unbeliever và mỗi cái có thể được tối ưu hóa để sắp xếp khác nhau do các yếu tố khác không hiển nhiên trong chính truy vấn. –

+0

@Damien_The_Unbeliever. . . Trong thực tế, MySQL đảm bảo thứ tự sau một 'nhóm by' (" Nếu bạn sử dụng GROUP BY, các hàng đầu ra được sắp xếp theo các cột GROUP BY như thể bạn có một ORDER BY cho cùng một cột. "Tại http: // dev.mysql.com/doc/refman/5.5/en/select.html). Tôi xem đây là một hạn chế lớn về khả năng MySQL tối ưu hóa các biểu thức tập hợp. Nó thậm chí không hỗ trợ tập hợp băm. –

Trả lời

44

Không có trật tự vốn có, bạn phải sử dụng ORDER BY. Ví dụ của bạn, bạn có thể dễ dàng làm điều này bằng cách thêm một SortOrder vào mỗi SELECT. Điều này sau đó sẽ lưu giữ hồ sơ theo thứ tự bạn muốn:

SELECT 'O', 1 SortOrder 
UNION ALL 
SELECT 'R', 2 
UNION ALL 
SELECT 'D', 3 
UNION ALL 
SELECT 'E', 4 
UNION ALL 
SELECT 'R', 5 
ORDER BY SortOrder 

Bạn không thể đảm bảo đơn đặt hàng trừ khi bạn cung cấp thứ tự cụ thể bằng truy vấn.

+0

+1 Câu trả lời hay hơn trước khi chỉnh sửa của Gordon. – Kermit

+2

Tôi nghe vô số người nói rằng nó sẽ không luôn luôn theo thứ tự, và tài liệu khác nhau, nhưng không có bằng chứng thực nghiệm - tôi muốn có thể chạy một truy vấn và thấy nó thực sự nhổ ra các kết quả theo thứ tự khác. – whytheq

+6

@whytheq không nhìn thấy gấu trong rừng khi đi lang thang không có nghĩa là không có gấu trong rừng. Ngay cả khi mệnh lệnh * có thể * được đảm bảo, bạn sẽ đạt được điều gì từ đó? Không phải gõ 'ORDER BY' trong trường hợp cụ thể này? Điều đó sẽ giúp bạn tiết kiệm rất nhiều năng suất hơn là rõ ràng.

37

Không, không. Các bảng SQL vốn không có thứ tự. Bạn cần sử dụng order by để nhận những thứ theo thứ tự mong muốn.

Vấn đề không phải là liệu nó có hoạt động một lần khi bạn dùng thử. Vấn đề là liệu bạn có thể tin tưởng hành vi này không. Và bạn không thể. SQL Server thậm chí không đảm bảo trật tự cho việc này:

select * 
from (select t.* 
     from t 
     order by col1 
    ) t 

Nó nói here:

Khi ORDER BY được sử dụng trong định nghĩa của một cái nhìn, chức năng nội tuyến, bảng có nguồn gốc, hoặc subquery, mệnh đề chỉ được sử dụng để xác định các hàng được trả về bởi mệnh đề TOP. Mệnh đề ORDER BY không đảm bảo kết quả đặt hàng khi các cấu trúc này được truy vấn, trừ khi ORDER BY cũng được chỉ định trong chính truy vấn đó.

Nguyên tắc cơ bản của ngôn ngữ SQL là các bảng không được sắp xếp. Vì vậy, mặc dù truy vấn của bạn có thể hoạt động trong nhiều cơ sở dữ liệu, bạn nên sử dụng phiên bản được đề xuất bởi BlueFeet để đảm bảo thứ tự các kết quả.

+1

Bao lần chúng ta chạy nó trên máy của ai đó, nó vẫn có vẻ đánh vần "ORDER"! ... chúng ta có thể chứng minh rằng đôi khi nó sẽ theo một thứ tự khác? – whytheq

+4

Đừng nghĩ về máy móc rời rạc. Hãy suy nghĩ về bộ. Bạn phải khai báo rõ ràng thứ tự của bộ nếu bạn cần nó được đặt hàng, nếu không nó chỉ đơn giản là một túi hàng. – Tim

+5

@whytheq - nó có thể trông giống nhau, nhưng đôi khi là thư thứ 2 và vị trí thay đổi thứ 5. –

5

No. Bạn nhận được bản ghi theo bất kỳ cách nào SQL Server tìm nạp chúng cho bạn. Bạn có thể áp dụng một lệnh vào một kết quả unioned do chỉ số 1 dựa trên thusly:

SELECT 1, 'O' 
UNION ALL 
SELECT 2, 'R' 
UNION ALL 
SELECT 3, 'D' 
UNION ALL 
SELECT 4, 'E' 
UNION ALL 
SELECT 5, 'R' 
ORDER BY 1 
+3

ORDER được viết "sai" ngay bây giờ vì thứ tự sắp xếp theo thứ tự bảng chữ cái. Nếu bạn thêm chỉ mục bằng số, bạn có thể buộc chính tả "đúng" của mình. Xem chỉnh sửa ở trên. –

+6

Bạn nên áp dụng bí danh cột cho cột và thứ tự đầu tiên theo đó. [Thứ tự theo vị trí thứ tự là một thói quen xấu] (http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/06/bad-habits-to-kick-order-by-ordinal.aspx) hoạt động tốt ở đây nhưng có thể phá vỡ ở nơi khác. –

+0

Thứ tự theo vị trí thứ tự rất thuận tiện cho việc phát triển nhanh chóng, nhưng không được hỗ trợ trong Oracle, chẳng hạn. –

16

Hãy thử xóa tất cả các ví dụ ALL. Hoặc thậm chí chỉ một trong số họ. Bây giờ hãy xem xét rằng loại tối ưu hóa phải xảy ra ở đó (và nhiều loại khác) cũng sẽ có thể khi truy vấn SELECT là các truy vấn thực tế đối với các bảng và được tối ưu hóa riêng biệt. Nếu không có ORDER BY, việc đặt hàng trong mỗi truy vấn sẽ tùy ý và bạn không thể đảm bảo rằng các truy vấn đó sẽ được xử lý theo bất kỳ thứ tự nào.

Nói UNION ALL không có số ORDER BY giống như nói "Chỉ cần ném tất cả các viên bi trên sàn." Có lẽ mỗi khi bạn ném tất cả các viên bi trên sàn nhà, chúng sẽ được sắp xếp theo màu sắc. Điều đó không có nghĩa là lần sau bạn ném chúng trên sàn nhà, chúng sẽ hoạt động theo cùng một cách. Điều này cũng đúng cho việc đặt hàng trong SQL Server - nếu bạn không nói ORDER BY thì SQL Server giả định bạn không quan tâm đến thứ tự. Bạn có thể thấy trùng hợp một thứ tự nhất định được trả lại mọi lúc, nhưng nhiều thứ có thể ảnh hưởng đến thứ tự tùy ý đã được chọn lần sau. Thay đổi dữ liệu, thay đổi thống kê, biên dịch lại, lập kế hoạch tuôn ra, nâng cấp, gói dịch vụ, hotfix, theo dõi cờ ... quảng cáo nauseum.

tôi sẽ đặt này bằng chữ lớn để làm cho nó rõ ràng:

Bạn không thể đảm bảo một trật tự mà không cần ORDER BY

Một số đọc thêm:

http://sqlblog.com/blogs/aaron_bertrand/archive/2010/02/08/bad-habits-to-kick-relying-on-undocumented-behavior.aspx

Ngoài ra, please read this post by Conor Cunningham, a pretty smart guy on the SQL team.

+2

Bạn có thể làm cho phông chữ đó lớn hơn một chút mà tôi không hiểu không? :) – Taryn

+3

@bluefeet chỉ khi nó được liên kết với một SQLfiddle. :-) –

+0

Tôi có thể thêm điều đó cho bạn nếu bạn muốn. – Taryn

Các vấn đề liên quan