SQL CTE и ORDER BY влияют на набор результатов - PullRequest
7 голосов
/ 13 октября 2010

Ниже я вставил очень упрощенную версию моего SQL-запроса. Проблема, с которой я сталкиваюсь, заключается в том, что оператор ORDER BY влияет на результаты выбора моего CTE. Я не смог понять, почему это так, я изначально думал, что в CTE я выполняю какое-то утверждение SELECT, тогда ORDER BY должно работать на ЭТИ результаты.

К сожалению, поведение, которое я наблюдаю, заключается в том, что мой внутренний оператор SELECT влияет на порядок, давая мне 'предметы', которых нет в TOP 10.

Вот пример данных: (Индексируется в обратном порядке по идентификатору)

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

Мой основной запрос:

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

запрос возвращает:

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

Мой запрос с ORDER BY

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

запрос возвращает:

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

Может кто-нибудь объяснить, почему первый запрос будет возвращать только те идентификаторы, которые находятся в верхней 10 таблицы, а второй запрос возвращает верхнюю 10 всей таблицы (после применения сортировки).

Ответы [ 2 ]

14 голосов
/ 13 октября 2010

Когда вы используете SELECT TOP n, вы должны предоставить ORDER BY, если вам нужно детерминированное поведение, в противном случае сервер может вернуть любые 10 строк, которые ему кажутся .Поведение, которое вы видите, совершенно корректно.

Чтобы решить проблему, укажите ORDER BY внутри CTE:

WITH results AS
(
    SELECT TOP 10 ID, Date
    FROM dbo.items
    ORDER BY ID DESC 
)
SELECT ID
FROM results
ORDER BY Date
3 голосов
/ 19 августа 2013

Я думаю, что вы можете добавить новый столбец, как

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

, а затем все ваши столбцы ... это поможет вам делать запросы, используя привязку CTE ... используя операторы where, where и т.д ..

...