CHỌN ROW_NUMBER () có được đảm bảo trả về kết quả được sắp xếp theo số hàng được tạo không?


10

Ví dụ: xem xét truy vấn SQL:

SELECT
   A.[Name],
   ROW_NUMBER() OVER(ORDER BY A.[Name] ASC)
FROM
   [FooTable] AS A

Ở đây tôi quan sát các kết quả được trả về được sắp xếp theo A. [Tên]. Nếu tôi thay đổi cột sắp xếp được xác định trong hàm ROW_NUMBER sang cột khác thì kết quả sẽ được sắp xếp theo cột đó.

Tôi đã mong đợi số hàng được gán cho các hàng nhưng tôi không mong đợi các hàng trở lại được sắp xếp theo cùng tiêu chí đó. Đây có phải chỉ đơn giản là một tác dụng phụ của cách thực hiện truy vấn (trong trường hợp của tôi trên SQL Server 2008 R2) hoặc hành vi này có được đảm bảo không? (Tôi không thể tìm thấy tài liệu tham khảo nào để đảm bảo như vậy).


10
Không bao giờ có bất kỳ đảm bảo. Không bao giờ. Trừ khi bạn nói với SQL Server cách đặt hàng một cái gì đó, bạn có thể trả lại dữ liệu theo bất kỳ thứ tự nào nó muốn. Bằng cách loại bỏ đơn đặt hàng trước, bạn đang nói với SQL Server rằng bạn không quan tâm đến đơn hàng. Nếu bạn muốn bảo lãnh, chỉ cần gõ mệnh đề ORDER BY.
Aaron Bertrand

Có một lý do chính đáng để hỏi vì mệnh đề theo thứ tự trong câu hỏi rất phức tạp và do đó việc sao chép tạo ra cả chấn lưu bảo trì mã cũng như tăng khả năng xảy ra lỗi trong tương lai. Một lựa chọn khác là một cấu trúc lại nhỏ mà tôi nghĩ rằng tôi có thể tránh được nếu tiêu chuẩn SQL xác định thứ tự sắp xếp ngầm định. Trong mọi trường hợp tôi chỉ quan tâm nếu có tài liệu chính thức về điểm này.
redcalx

1
vậy tại sao không hỏi câu hỏi đó?
Aaron Bertrand

Câu trả lời:


14

Nếu bạn đã hỏi câu hỏi tôi nghĩ bạn thực sự muốn hỏi:

Làm thế nào tôi có thể đặt hàng bằng cách ROW_NUMBER()không lặp lại ORDER BYbiểu thức phức tạp ?

Chúng tôi có thể bảo bạn tạo bí danh cho ROW_NUMBER()biểu thức và sau đó sắp xếp bằng bí danh:

SELECT
   A.[Name],
   rn = ROW_NUMBER() OVER (ORDER BY <complex expression>)
FROM
   dbo.[FooTable] AS A
ORDER BY rn;

Bây giờ bạn chỉ phải thay đổi biểu thức ở một nơi và sắp xếp kết quả sẽ dựa trên biểu thức đó mà không phải lặp lại biểu thức đó.


6
Trên thực tế, repeating the complex ORDER BY expressionthậm chí không đảm bảo đầu ra sẽ xuất hiện theo thứ tự ROW_NUMBER (). Trừ khi các cột trong mệnh đề ORDER BY tạo thành một khóa duy nhất.
孔夫子

22

Tuyệt đối không. Bằng chứng:

SELECT
   A.[Name],
   ROW_NUMBER() OVER(ORDER BY A.[Name] ASC),
   ROW_NUMBER() OVER(ORDER BY A.[Name] DESC)
FROM
   [FooTable] AS A

Cách duy nhất để đảm bảo một đơn hàng trong SQL là yêu cầu, sử dụng ORDER BYchính kết quả đó.


OK Tôi sẽ thêm một tiêu chuẩn nữa - là các kết quả được đảm bảo sẽ được sắp xếp nếu chỉ một điều khoản ROW_NUMBER () được chỉ định.
redcalx

22
Cách duy nhất để đảm bảo một đơn hàng trong SQL là yêu cầu nó
Remus Rusanu

0

Trên thực tế, câu hỏi (cũ) có thể được mở rộng để bao gồm phân vùng theo từng phần, vì dường như có một thứ tự ngầm trước tiên là phân vùng và sau đó là thứ tự theo từng phần

Vì vậy, nó không hoàn toàn đơn giản như một số người đã gợi ý khi gán row_number và sử dụng nó để đặt hàng.

Chúng ta cũng cần một sql lồng nhau trích xuất phân vùng theo mệnh đề (nếu chúng ta không muốn đơn giản lặp lại nó)

Theo kinh nghiệm, chúng tôi dường như nhận được dòng đặt hàng cuối cùng

Select
  <field-list>, 
  rn=Row_Number() over(partition by <PartionClause>) order by <OrderClause>
from ....
Order by <PartionClause> asc, rn asc

Nhưng những gì chúng ta thiếu là bất kỳ bằng chứng hoặc đảm bảo rằng nó luôn luôn giữ.

(Nếu có nhiều cuộc gọi Row_Number () đang diễn ra, thì đó là cuộc gọi LẦN dường như đưa ra thứ tự)

Cũng lưu ý nếu bạn rõ ràng thêm trật tự của kế hoạch thực hiện rõ ràng cho thấy một loại bước cuối cùng, và sắp xếp một bộ đã được sắp xếp là loại trường hợp xấu nhất, vì thế phải mất một thời gian tương với ! Sắp xếp theo hơn không


1
Điều này không thực sự trả lời câu hỏi và dường như không đồng ý với cả câu trả lời được chấp nhận và câu trả lời được đánh giá cao.
Erik Darling

Tôi đồng ý rằng của tôi là một nhận xét nhiều hơn là một câu trả lời. Vâng, câu trả lời được chấp nhận không thực sự là một câu trả lời, ngoại trừ nó nói rằng tốt hơn là chúng ta không nên tin vào đơn đặt hàng - và đó là câu hỏi gì. Có thể thấy kế hoạch thực hiện rằng nó thực sự thực hiện một loại và nếu chúng ta thêm một thứ tự rõ ràng bằng cách, chúng ta sẽ có được một loại thứ hai. Nhưng đó KHÔNG phải là một bằng chứng, nó chỉ là một phần của kiến ​​thức thực nghiệm
Eske Rahn

(Tất nhiên nó chỉ làm các loại nếu không có một chỉ số thích hợp nó có thể sử dụng để truy cập vào bảng, nhưng chỉ thêm nó để chứng minh rằng nó không phải là thường chi phí miễn phí để cung cấp cho một cách rõ ràng trình tự do)
Eske Rahn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.