2010-10-13 16 views
6

Tôi đã dán một phiên bản rất đơn giản của truy vấn SQL bên dưới. Vấn đề mà tôi đang gặp phải là tuyên bố ORDER BY đang ảnh hưởng đến các kết quả lựa chọn của CTE của tôi. Tôi đã không thể hiểu tại sao điều này là, suy nghĩ ban đầu của tôi là trong CTE, tôi thực hiện một số tuyên bố SELECT, sau đó các ORDER BY nên làm việc trên kết quả THOSE.SQL CTE và ORDER BY ảnh hưởng đến tập kết quả

Thật không may là hành vi mà tôi thấy là tuyên bố bên trong SELECT của tôi đang bị ảnh hưởng bởi lệnh, cho tôi 'các mặt hàng' không nằm trong số TOP 10.

Dưới đây là một ví dụ về dữ liệu: (Indexed theo thứ tự ngược bởi ID)

ID, Date 
9600 2010-10-12 
9599 2010-09-08 
9598 2010-08-31 
9597 2010-08-31 
9596 2010-08-30 
9595 2010-08-11 
9594 2010-08-06 
9593 2010-08-05 
9592 2010-08-02 
.... 
9573 2010-08-10 
.... 
8174 2010-08-05 
.... 
38 2029-12-20 

truy vấn cơ bản của tôi:

;with results as(
select TOP 10 ID, Date 
from dbo.items 
) 
SELECT ID 
FROM results 

truy vấn trả về:

ID, Date 
9600 2010-10-12 
9599 2010-09-08 
9598 2010-08-31 
9597 2010-08-31 
9596 2010-08-30 
9595 2010-08-11 
9594 2010-08-06 
9593 2010-08-05 
9592 2010-08-02 

truy vấn của tôi với các truy vấn ORDER BY

;with results as(
select TOP 10 ID, Date 
from dbo.items 
) 
SELECT ID 
FROM results 
ORDER BY Date DESC 

trả:

ID, Date 
38 2029-12-20 
9600 2010-10-12 
9599 2010-09-08 
9598 2010-08-31 
9597 2010-08-31 
9596 2010-08-30 
9595 2010-08-11 
9573 2010-08-10 
9594 2010-08-06 
8174 2010-08-05 

bất cứ ai có thể giải thích lý do tại sao các truy vấn đầu tiên sẽ chỉ trả lại ID mà nằm trong top 10 của bảng và truy vấn thứ hai trả về 10 đầu của toàn bộ bảng (sau khi sắp xếp được áp dụng).

Trả lời

10

Khi bạn sử dụng SELECT TOP n bạn phải cung cấp một ORDER BY nếu bạn muốn hành vi xác định nếu không thì máy chủ là miễn phí để trở bất kỳ 10 dòng nó cảm thấy như. Hành vi bạn đang thấy là hoàn toàn hợp lệ.

Để giải quyết vấn đề, xác định một ORDER BY bên trong CTE:

WITH results AS 
(
    SELECT TOP 10 ID, Date 
    FROM dbo.items 
    ORDER BY ID DESC 
) 
SELECT ID 
FROM results 
ORDER BY Date 
+0

Tôi đoán là tôi muốn nó trả về 10 hàng đầu từ bảng và sau đó sắp xếp theo 10 hàng trên cùng đó, không đặt hàng toàn bộ bảng và choo lọt vào top 10 từ bộ đó ... hiểu lầm của tôi ở đâu? – Brett

+2

@Brett - Bạn cần phải thông báo cho cơ sở dữ liệu ý bạn là gì bởi "10 hàng hàng đầu từ bảng". Top 10 theo chỉ số nào? Có lẽ được sắp xếp theo ngày? –

+0

Vì vậy, bạn có nói rằng tôi cần phải có một đơn đặt hàng bởi trong CTE? Vì vậy: '; với kết quả là (SELECT TOP 10 ID, đã đăng từ các mục ORDER BY ID desc)'? .... Sự nhầm lẫn của tôi xuất phát từ lý do tại sao 'ORDER BY' bên ngoài CTE ảnh hưởng đến kết quả CTE? – Brett

1

Tôi nghĩ rằng bạn có thể thêm cột mới như

SELECT ROW_NUMBER() OVER(ORDER BY <ColumnName>;) AS RowNo 

và sau đó tất cả các cột của bạn .. điều này sẽ giúp bạn để truy vấn bằng cách sử dụng neo CTE ... sử dụng giữa, ở đó mệnh đề ..

+0

đó là câu trả lời đúng. – hoanvd1210

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