Можете ли вы сказать нам порядок, в соответствии с которым вы хотите «топ 1»?
Эндрю Вульф
1
Прежде всего, вам никогда не следует полагаться на движок БД для этого. Если вы хотите узнать такие вещи, вставьте секвенсор. При этом гарантируется, что они будут пронумерованы в том порядке, в котором они были вставлены.
Это хорошо, если вы хотите только 1 ряд и не волнует какой. Если вам нужны определенные строки, например самая последняя запись, вам нужно выполнить сортировку в подвыборке, например, в ответе Vash. Oracle назначает rownums перед сортировкой.
Скотт Бейли
4
@ Скотт да это верно. И Патрик, хорошо, я думаю, что синтаксис неверен в этом. Это действительно должно быть удержание в памяти (dens_rank () last ...)
mcpeterson
2
Разница между первым и вторым примером заключается в том, что первый выбирает строку (любая строка без порядка). Второй пример получает значение первой строки, не выполняя внутренний запрос заказа (согласно примерам ниже).
JulesLt
3
Неправильный синтаксис в: выберите max (fname) over (rank () по порядку some_factor) из MyTbl
Стефан Гербер
1
@jclozano "не очень известная функциональность оракула" - С уважением, я позволю себе не согласиться. Это важно, потому что «недостаточно известная функциональность» имеет тенденцию подразумевать неясность и, следовательно, может указывать на то, что нам следует избегать использования. Это неясно, и его использование не следует избегать.
Интересная команда, я использую здесь 12c, и, OFFSET 0 ROWSвидимо, в этом нет необходимости, вы можете использовать FETCH NEXT 1 ROWS ONLYили даже FETCH FIRST ROW ONLY, порядок по важен, или он будет эквивалентен простому использованию WHERE rownum = 1. Я даже пробовал это в инструкции OUTER APPLY, и она работала как функция TOP Ms-SQL там.
Рафаэль Мерлин
Вы правы @RafaelMerlin. После вашего поста я понял, что OFFSET 0 ROWS не нужен. Это было бы полезно при получении данных между вершиной X и вершиной Y.
Пока все хорошо, с важным упущением TIES. Направьте это в тех случаях, когда связи происходят для версии 12c +и12c -
Barbaros Özhan
10
Вы можете использовать ROW_NUMBER()с ORDER BYпредложением в подзапросе и использовать этот столбец вместо TOP N. Это можно объяснить пошагово.
Смотрите таблицу ниже, у которой есть два столбца NAMEи DT_CREATED.
Если вам нужно взять только первые две даты, независимо от того NAME, вы можете использовать следующий запрос. Логика была написана внутри запроса
-- The number of records can be specified in WHERE clauseSELECT RNO,NAME,DT_CREATED
FROM(-- Generates numbers in a column in sequence in the order of dateSELECT ROW_NUMBER()OVER(ORDERBY DT_CREATED)AS RNO,
NAME,DT_CREATED
FROM DEMOTOP
)TAB
WHERE RNO<3;
РЕЗУЛЬТАТ
В некоторых ситуациях нам нужно выбрать TOP Nрезультаты, соответствующие каждому NAME. В таком случае мы можем использовать PARTITION BYс ORDER BYпредложением в подзапросе. Обратитесь к следующему запросу.
-- The number of records can be specified in WHERE clauseSELECT RNO,NAME,DT_CREATED
FROM(--Generates numbers in a column in sequence in the order of date for each NAMESELECT ROW_NUMBER()OVER(PARTITIONBY NAME ORDERBY DT_CREATED)AS RNO,
NAME,DT_CREATED
FROM DEMOTOP
)TAB
WHERE RNO<3;
Использование ROW_NUMBER () ... более правильное решение, чем в тематическом ответе. Одна проблема с этим решением (и с макс. (Полевым) вариантом), что вы не можете делать такие вещи, как «выберите ... (выберите ROW_NUMBER () ...) для обновления ;»
Алексо По.
И это иногда очень важно в PL / SQL (извините, не удалось отредактировать предыдущий комментарий за 5 минут).
Алексо По.
В таком случае мы можем использовать CTE как во внешней части. Правильно? @ Алексо По.
Сарат Аванаву
Я думаю, что я вас не понимаю. Предложение for update можно использовать, когда ROWID «легко» сохраняется Oracle. Таким образом, группировка (и группировка из-за использования аналитического предложения) скрывает реальный ROWID, и строки не могут быть заблокированы. И, во-вторых, CTE ( with (select ... ) as предложение) ничего не меняет в этой проблеме, CTE просто стремится читать и поддерживать запросы. Правильно? @ Сарат Аванаву
Алексо По.
Обратите внимание на себя. Проблема с ROWID на самом деле происходит именно из-за того, что условие RNO <3 , в этом случае значение RNO не связано с ROWID, поэтому Oracle не может блокировать строки.
Алексо По.
9
Вы можете сделать что-то вроде
SELECT*FROM(SELECT Fname FROM MyTbl ORDERBY Fname )WHERE rownum =1;
Вы также можете использовать аналитические функции RANK и / или DENSE_RANK , но ROWNUM , вероятно, самый простой.
@carpenteri: Да, аналитика была доступна в 8i - не могу вспомнить подробности, но аналитика не была доступна широкой публике до 9i.
OMG Ponies
Небольшой комментарий - ответ Vash ниже включает ORDER BY на внутренний запрос, который имеет решающее значение, если вы хотите, чтобы значение TOP имело значение fname, а не 'first' (который может быть любым, скорее всего, вставлена первая строка). Может быть стоит редактировать?
JulesLt
@JulesLt: запрос, предоставленный OP, не включает ORDER BY, поэтому этот ответ представляет собой точный перевод к синтаксису Oracle.
OMG Ponies
Мое недопонимание синтаксиса SQL SERVER TOP (ошибочно предположил, что он был похож на FIRST в RANK, а не ROWNUM). Проголосовал.
JulesLt
3
Чтобы выбрать первую строку из таблицы и выбрать одну строку из таблицы, это две разные задачи, и для них требуется другой запрос. Есть много возможных способов сделать это. Четыре из них:
Первый
select max(Fname)from MyTbl;
второй
select min(Fname)from MyTbl;
Третий
select Fname from MyTbl where rownum =1;
четвертый
select max(Fname)from MyTbl where rowid=(select max(rowid)from MyTbl)
Ответы:
Если вы хотите просто первую выбранную строку, вы можете:
Вы также можете использовать аналитические функции для заказа и взять верхний x:
источник
источник
top X
можно изменить наWHERE ROWNUM <= X
С участием Oracle 12c (июнь 2013 г.) вы можете использовать его следующим образом.
источник
OFFSET 0 ROWS
видимо, в этом нет необходимости, вы можете использоватьFETCH NEXT 1 ROWS ONLY
или дажеFETCH FIRST ROW ONLY
, порядок по важен, или он будет эквивалентен простому использованиюWHERE rownum = 1
. Я даже пробовал это в инструкции OUTER APPLY, и она работала как функция TOP Ms-SQL там.TIES
. Направьте это в тех случаях, когда связи происходят для версии12c +
и12c -
Вы можете использовать
ROW_NUMBER()
сORDER BY
предложением в подзапросе и использовать этот столбец вместоTOP N
. Это можно объяснить пошагово.Смотрите таблицу ниже, у которой есть два столбца
NAME
иDT_CREATED
.Если вам нужно взять только первые две даты, независимо от того
NAME
, вы можете использовать следующий запрос. Логика была написана внутри запросаРЕЗУЛЬТАТ
В некоторых ситуациях нам нужно выбрать
TOP N
результаты, соответствующие каждомуNAME
. В таком случае мы можем использоватьPARTITION BY
сORDER BY
предложением в подзапросе. Обратитесь к следующему запросу.РЕЗУЛЬТАТ
источник
with (select ... ) as
предложение) ничего не меняет в этой проблеме, CTE просто стремится читать и поддерживать запросы. Правильно? @ Сарат АванавуВы можете сделать что-то вроде
Вы также можете использовать аналитические функции RANK и / или DENSE_RANK , но ROWNUM , вероятно, самый простой.
источник
источник
Использование:
При использовании Oracle9i + вы можете использовать аналитические функции, такие как ROW_NUMBER (), но они не будут работать так же хорошо, как ROWNUM .
источник
Чтобы выбрать первую строку из таблицы и выбрать одну строку из таблицы, это две разные задачи, и для них требуется другой запрос. Есть много возможных способов сделать это. Четыре из них:
Первый
второй
Третий
четвертый
источник
У меня была та же проблема, и я могу исправить это с помощью этого решения:
Вы можете заказать свой результат, прежде чем иметь первое значение сверху.
Удачи
источник