В некоторых других базах данных (например, DB2 или Oracle с ROWNUM
) я могу опустить предложение ORDER BY
в предложении OVER()
функции ранжирования. Например:
ROW_NUMBER() OVER()
Это особенно полезно при использовании с упорядоченными производными таблицами, такими как:
SELECT t.*, ROW_NUMBER() OVER()
FROM (
SELECT ...
ORDER BY
) t
Как это можно эмулировать в SQL Server? Я нашел людей, использующих это трюк, но это неправильно, так как он будет вести себя недетерминированно по отношению к порядку из производной таблицы:
-- This order here ---------------------vvvvvvvv
SELECT t.*, ROW_NUMBER() OVER(ORDER BY (SELECT 1))
FROM (
SELECT TOP 100 PERCENT ...
-- vvvvv ----redefines this order here
ORDER BY
) t
Конкретный пример (как можно увидеть на SQLFiddle):
SELECT v, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) RN
FROM (
SELECT TOP 100 PERCENT 1 UNION ALL
SELECT TOP 100 PERCENT 2 UNION ALL
SELECT TOP 100 PERCENT 3 UNION ALL
SELECT TOP 100 PERCENT 4
-- This descending order is not maintained in the outer query
ORDER BY 1 DESC
) t(v)
Кроме того, я не могу повторно использовать какое-либо выражение из производной таблицы для воспроизведения предложения ORDER BY
в моем случае, поскольку производная таблица может быть недоступна, поскольку она может быть предоставлена какой-то внешней логикой.
Итак, как я могу это сделать? Могу ли я это сделать вообще?
SELECT NULL
? это все равно даст неверный результат? - person John Woo   schedule 23.09.2013OVER()
четко определено, или это работает по совпадению в DB2... Я подготовлю SQL Fiddle, чтобы проиллюстрировать это. - person Lukas Eder   schedule 23.09.2013DISTINCT
, в случае чего добавлениеROW_NUMBER()
изменит семантику внутреннего запроса. - person Lukas Eder   schedule 23.09.2013top 100%
является проблемой? (как вtop 10000000000
работает), хотя, если вы не можете изменить внутренний запрос, можете ли вы добавить ограничение сверху? - person   schedule 23.09.2013top 100%
,top N
. Я просто хочу быть готовым к любому внутреннему запросу, который я получаю, например. когда у него есть пунктTOP .. ORDER BY
... - person Lukas Eder   schedule 23.09.2013ORDER BY
только к последнему запросуTOP
или если он заказывает весь набор. Попробуйте изменить порядок строк, которыеUNIONed
вместе, и посмотрите, получится ли у вас тот же результат? - person ErikE   schedule 25.09.2013ORDER BY
применяется к результату всех объединенных подзапросов. В SQL Server есть<SELECT statement> ::= <query_expression> [ ORDER BY ]
, как видно здесь: technet.microsoft.com /de-de/library/ms189499.aspx. Так что я не думаю, что есть какая-то двусмысленность - person Lukas Eder   schedule 25.09.2013ORDER BY
применяется только к четвертому SELECT во внутреннем запросе. Но когда этот запрос переносится на верхний уровень,ORDER BY
работает для ОБОИХ значений: выбор конкретных строк в финальном SELECT а также упорядочение всего набора результатов. Мое чутье насчет возможной двусмысленности не было ошибочным. - person ErikE   schedule 26.09.2013UNION
иORDER BY
есть какая-то двусмысленность :-) Внешний запрос в вашем первом примере просто не содержит предложенияORDER BY
, и SQL-сервер не дает вам никаких гарантий в отношении порядка, тогда... - person Lukas Eder   schedule 27.09.2013ORDER BY
выбрал7
и6
для последнихUNION ALL
, доказывая, чтоORDER BY
применялся только к последнимSELECT
. Во втором запросе он делал то же самое: выбирал только7
и6
и также упорядочивал окончательный результат. Таким образом, последняяORDER BY
в серииUNIONs
может функционировать по-разному, поэтому я считаю, что двусмысленность все еще присутствует. Примечание. У меня была опечатка в скрипке, которая не изменила набор результатов, но слегка испортила его, поэтому вот вам обновленный SQL Fiddle. - person ErikE   schedule 27.09.2013