Select top: TOP (Transact-SQL) — SQL Server

sql — Каков синтаксис для функционального аналога SELECT TOP(N) в Oracle?

Предположим, есть таблица TABLE

ID | DEF
 1 | Один
 2 | Два
 3 | Три
 4 | Четыре

Тогда запрос в MS SQL Server

SELECT TOP(2) * FROM TABLE ORDER BY ID DESC

Даст нам выдачу:

ID | DEF
 4 | Четыре
 3 | Три

А аналогичный запрос в Oracle (аналог, который мне предложился в интернетах)

SELECT * FROM TABLE WHERE ROWNUM <= 2 ORDER BY ID DESC

Даст нам выдачу:

ID | DEF
 2 | Два
 1 | Один

Как получить действительно аналогичный по функциональности синтаксис для Oracle?

  • sql
  • база-данных
  • sql-server
  • oracle
  • plsql-developer

0

В оракле до 11-й версии включительно — через подзапрос с row_number:

select *
  from (select t.*, row_number() over (order by id desc) rn
          from t)
 where rn <= 2

В 12-й версии появился синтаксис для первых N строк с

LIMIT и OFFSET, почти как в постгресе (запрос скопипастил из интернета, 12-го оракла под рукой нет):

 select *
   from t
  order by id desc
 OFFSET 5 ROWS FETCH NEXT 5 ROWS ONLY;

Дело в том, что Oracle сначала выполняет условие where и только потом производит сортировку. То есть в вашем случае сначала остаются строки с id in (1, 2) и потом они и сортируются.

Для получения аналогичного результата сначала надо отсортировать все данные и потом обернув запрос получить нужное количество строк:

SELECT * 
FROM (SELECT * 
      FROM   TABLE 
      ORDER  BY ID DESC) 
WHERE ROWNUM <= 2

Вам придётся воспользоваться подзапросом. Т.е. ваш запрос с основными условиями и сортировкой перенесите в подзапрос, а ограничение на выбор поставьте в секцию WHERE внешнего запроса.

SELECT * 
FROM
  (
  SELECT * 
  FROM TABLE 
  ORDER BY ID DESC 
  )
WHERE 
ROWNUM <= 2 

1

Начиная с версии 12.1.0.1 Oracle БД поддерживает введённый в стандарте SQL:2008 FETCH FIRST|NEXT синтаксис (см. row_limiting_clause для полного описания).

Воспроизводимый рабочий пример:

with tab (id, def) as (
    select rownum, trim (column_value)
    from xmlTable ('"Один", "Два", "Три", "Четыре"')
) 
select *
from tab
order by id desc
fetch first 2 rows only;

Результат:

        ID DEF       
---------- ----------
         4 Четыре    
         3 Три       

Надо отметить, что поддерживаемый MS SQL Server SELECT TOP(N) синтаксис не является стандартным.

Зарегистрируйтесь или войдите

Регистрация через Google

Регистрация через Facebook

Регистрация через почту

Отправить без регистрации

Почта

Необходима, но никому не показывается

Отправить без регистрации

Почта

Необходима, но никому не показывается

Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки

Подробнее о TOP / Хабр

В прошлой статье я писал об особом виде оператора TOP, известного как ROWCOUNT TOP.

 Теперь рассмотрим несколько других интересных сценариев появления в плане оператора TOP. 

В общем случае, ТОР — довольно приземленный оператор. Он просто подсчитывает и возвращает заданное количество строк. SQL Server 2005 включает в себя два усовершенствования этого оператора, которых не было в SQL Server 2000.

Во-первых, в SQL Server 2000 можно указать только константу в виде целого числа возвращаемых строк. В SQL Server 2005 мы можем указать произвольное выражение, включая выражение, содержащее переменные или параметры T-SQL. 

Во-вторых, SQL Server 2000 допускает только TOP в операторе SELECT (хотя он поддерживает ROWCOUNT TOP в операторах INSERT, UPDATE и DELETE). SQL Server 2005 допускает TOP с операторами SELECT, INSERT, UPDATE и DELETE.

В этой статье мы сосредоточимся на нескольких простых примерах с оператором SELECT. Для начала создадим небольшую таблицу:

CREATE TABLE T (A INT, B INT)
CREATE CLUSTERED INDEX TA ON T(A)
SET NOCOUNT ON
DECLARE @i INT
SET @i = 0
WHILE @i < 100
  BEGIN
    INSERT T VALUES (@i, @i)
    SET @i = @i + 1
  END
SET NOCOUNT OFF

План простейшего запроса с TOP не нуждается в пояснениях:

SELECT TOP 5 * FROM T
Rows   Executes
5      1        |--Top(TOP EXPRESSION:((5)))
5      1             |--Clustered Index Scan(OBJECT:([tempdb]. [dbo].[T].[TA]))

TOP часто используется в сочетании с ORDER BY. Сочетание TOP с ORDER BY способствует детерминированности выборки. Без ORDER BY выборка зависит от плана запроса и даже может меняться от выполнения к выполнению. Если у нас есть подходящий индекс для поддержки выбранного порядка строк, план запроса останется простым (обратите внимание на ключевые слова ORDERED FORWARD):

SELECT TOP 5 * FROM T ORDER BY A
Rows   Executes
5      1        |--Top(TOP EXPRESSION:((5)))
5      1             |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[T].[TA]), ORDERED FORWARD)

Обратите внимание что, если нет подходящего индекса для выборки первых 5 строк SQL Server должен просмотреть все 100 строк таблицы. Также обратите внимание, что сортировка в этом сценарии будет «TOP sort». Такая сортировка обычно использует меньше памяти, чем обычная сортировка, поскольку ей нужно прокрутить через алгоритм сортировки только несколько топовых строк, а не всю таблицу.

Теперь давайте рассмотрим, что произойдет, если мы запросим TOP 5% строк.  Чтобы это определить. Для получения результата SQL Server должен подсчитать все строки и вычислить 5%. Это делает запросы, использующие TOP PERCENT, менее эффективными, чем запросы, использующие TOP с абсолютным числом строк.

SELECT TOP 5 PERCENT * FROM T
Rows   Executes
5      1        |--Top(TOP EXPRESSION:((5.000000000000000e+000)) PERCENT)
5      1             |--Table Spool
100    1                 |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[T].[TA]))

Как и в предыдущем примере, SQL Server будет просматривать все 100 строк таблицы. Тут SQL Server использует «жадную» очередь (Eager Spool), которая буферизует и подсчитывает все входные строки, прежде чем что-либо возвращать. Затем TOP запрашивает число строк в очереди, вычисляет 5% и продолжает работу, как любой другой TOP.

Если SQL Server в плане запроса должен выполнять сортировку, этим он также может обеспечить подсчёт затронутых строк. Однако только обычная сортировка умеет подсчитывать их количество.  Сортировка «TOP sort» должна знать какое число строк необходимо вернуть с самого начала.

SELECT TOP 5 PERCENT * FROM T ORDER BY B
Rows   Executes
5      1        |--Top(TOP EXPRESSION:((5.000000000000000e+000)) PERCENT)
5      1             |--Sort(ORDER BY:([tempdb].[dbo].[T].[B] ASC))
100    1                  |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[T].[TA]))

TOP WITH TIES также несовместим с «TOP sort». TOP WITH TIES не позволяет узнать наверняка, сколько строк будет получено, пока не будет вычитаны все «привязки». В нашем примере давайте сделаем «привязку» для пятой строки:

INSERT T VALUES (4, 4)
SELECT TOP 5 WITH TIES * FROM T ORDER BY B
Rows   Executes
6      1        |--Top(TOP EXPRESSION:((5)))
7      1             |--Sort(ORDER BY:([tempdb].[dbo].[T].[B] ASC))
101    1                  |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[T].[TA]))

В этом представлении плана нет TOP WITH TIES, но при SHOWPLAN_ALL или STATISTICS PROFILE можно увидеть следующее: «TIE COLUMNS:([T].

[B])». Это также доступно в графическом и XML-планах запроса для SQL Server 2005. Обратите внимание, что TOP теперь возвращает на одну строку больше. Когда TOP N WITH TIES достигает N-й строки, он хранит копию для привязки значения столбца этой строки (в примере B==4) и сравнивает каждую следующую в выборке строку с этим значением. Если есть подходящие строки, он их все вернёт в результате запроса. Поскольку TOP вынужден сравнивать значения всех оставшихся строк, пока не выберет все совпадения для первых N строк, в нашем примере TOP извлечёт из сортировки на одну строку больше, чем было до него.

Наконец, есть пара вырожденных случаев, когда оптимизатор знает, что TOP 0 и TOP 0 PERCENT никогда ничего не возвращают, и заменяет любой такой план запроса на сканирование константы:

SELECT TOP 0 * FROM T
  |--Constant Scan

Оптимизатор также знает, что TOP 100 PERCENT всегда возвращает все строки и удаляет оператор TOP из плана запроса:

SELECT TOP 100 PERCENT * FROM T
  |--Clustered Index Scan(OBJECT:([tempdb]. [dbo].[T].[TA]))

Для этих случаев требуется, чтобы количество строк было постоянным. Например, использование выражения, включающего переменную или параметр T-SQL, приведёт к тому, что план запроса будет такой же, как в общем случае. Оба описанных упрощения плана также работают и с операторами INSERT, UPDATE и DELETE.

Обратите внимание, что не рекомендуется использовать TOP для обхода ограничений языка SQL на использование ORDER BY в подзапросах или представлениях или для принудительного определенных порядка использования операторов в плане запроса.

SQL Выберите Верх | Укажите предел с помощью оператора Top в SQL

Мы можем получить набор результатов из запросов, указав максимальное количество записей, которые могут быть извлечены из запроса с помощью оператора top в SQL. При работе с огромными базами данных, включающими запросы к таблицам, которые содержат огромный набор записей, а результирующий набор результатов также включает слишком много записей, так что системе становится тяжело справляться, и это может даже привести к зависанию системы на долгое время.

продолжительность или иногда сбой, из запроса можно получить ограниченное количество записей, что снижает нагрузку на систему.

Мы можем указать предел, используя оператор top в SQL. Однако многие СУБД не поддерживают использование основных операторов, таких как MySQL и oracle. Они предоставляют альтернативный способ, такой как предложение LIMIT и ROWNUM в MySQL и Oracle соответственно. В этой статье мы изучим общий синтаксис предложения TOP в SQL и рассмотрим его использование и реализацию с помощью определенных примеров.

Синтаксис:

Синтаксис верхней части выбора показан ниже –

SELECT TOP (числовое_выражение) [ПРОЦЕНТ] [СО СВЯЗЬМИ] FROM
name_of_table
ORDER BY
name_of_column;

Числовое выражение может быть числом строк, которые должны быть извлечены в конечном наборе результатов после выполнения оператора запроса. Использование ключевого слова PERCENT является необязательным, и если оно указано, числовое выражение рассматривается как значение с плавающей запятой, указывающее процент результирующего набора, который должен быть извлечен, вместо количества строк. Когда PERCENT не используется, числовое выражение представляет собой значение BIGINT, указывающее количество записей, которые необходимо извлечь из запроса на выборку. Имя_таблицы — это имя таблицы, из которой должны быть извлечены записи, а имя столбца — это имя столбца, по которому должен быть отсортирован результат.

Использование предложения ORDER BY в верхней части выбора необязательно. Однако рекомендуется использовать оператор TOP вместе с предложением order by, так как это заставит запрос получить упорядоченный набор результатов, содержащий ограниченное количество записей, которые появляются первыми в последовательности порядка.

Предложение WITH TIES также является необязательным, в нем упоминается, что все связанные записи упорядоченного набора результатов также должны быть извлечены. Использование WITH TIES может увеличить число извлеченных наборов результатов, чем указано в числовом выражении. Например, если мы пытаемся получить человека с наибольшим количеством баллов в классе, а вы используете TOP 1, то, если вы не используете WITH LIES, набор результатов даст только одну запись, даже если существуют те же самые люди с оценкой, которые имеют достигли наивысших результатов. А при использовании TOP1 вместе с предложением «WITH LIES» это приведет к извлечению всех записей, имеющих самые высокие баллы в классе.

Примеры SQL Select Top

Рассмотрим одну существующую таблицу с именем educba_articles в нашей базе данных с именем educba. Содержимое и структуру таблицы можно получить, выполнив следующий запрос:

SELECT * FROM `educba_articles`;

Выполнение приведенного выше оператора запроса дает результат, показанный ниже.

Теперь мы можем заметить, что таблица educba_articles состоит из 20 записей. Мы хотим получить только первые 10 записей, которым назначена максимальная ставка. Для этого мы можем использовать предложение select top в SQL, используя следующий оператор запроса, который извлекает имя, автора и рейтинг статьи.

ВЫБЕРИТЕ ТОП 10
ИМЯ,
автор,
рейтинг
ИЗ
educba.`educba_articles`
ORDER BY Rate DESC ;

Выполнение приведенного выше оператора запроса дает результат, показанный ниже.

Использование предложения WITH TIES

Предположим, что у нас есть шесть самых первых записей статей, перечисленных в соответствии с их оценками, и мы должны найти из них статьи с наивысшим рейтингом. Если мы просто используем оператор top, как показано в приведенном выше операторе запроса, мы будем использовать следующий запрос.

ВЫБЕРИТЕ ТОП 6
ИМЯ,
автор,
рейтинг
ИЗ
educba.`educba_articles`
ORDER BY Rate DESC ;

Выполнение приведенного выше оператора запроса дает результат, показанный ниже.

Но мы можем заметить, что еще две статьи оцениваются так же, как ставки извлеченных целых записей, и в которых таблица educba_article. Поскольку мы хотим получить самые высокооплачиваемые записи, которые находятся в первых шести позициях, они также должны быть получены, поскольку им также назначена одинаковая ставка. Эту проблему можно решить, просто используя WITH TIES в том же операторе запроса, как показано ниже.

ВЫБЕРИТЕ ТОП-6 СО СВЯЗЯМИ
ИМЯ,
автор,
рейтинг
ИЗ
educba.`educba_articles`
СОРТИРОВАТЬ ПО рейтингу DESC ;

Выполнение приведенного выше оператора запроса дает результат, который показан ниже:

Здесь NOT NULL и где именованные статьи извлекаются из-за использования WITH TIES в предложении top в нашем операторе запроса select.

Использование PERCENT

Предположим, что мы хотим получить только 1/4 набора результатов оператора запроса. Для таких случаев мы можем использовать предложение PERCENT. 1/4 суммы чего-либо означает скидку 25% на эту вещь. Следовательно, упомянув 25 PERCENT в верхнем предложении, мы можем получить 1/4 записей исходного набора результатов запроса. Так как наша таблица содержит 20 записей. 25 процентов записей из 20 записей будут составлять 5 записей. Следовательно, использование следующего оператора запроса должно привести к извлечению первых пяти записей, упорядоченных на основе их скоростей в порядке убывания.

ВЫБЕРИТЕ ТОП 25 ПРОЦЕНТОВ
ИМЯ,
автор,
рейтинг
ИЗ
educba.`educba_articles`
ORDER BY Rate DESC ;

Выполнение приведенного выше оператора запроса дает результат, который соответствует ожидаемому и показан ниже.

Заключение

Использование оператора SELECT TOP в SQL помогает ограничить количество записей, которые будут извлечены из оператора запроса в SQL. Многие СУБД, такие как MySQL и oracle, не поддерживают его использование, но предоставляют альтернативы, такие как LIMIT и ROWNUM, которые можно использовать для ограничения набора результатов.

Рекомендуемые статьи

Это руководство по SQL Select Top. Здесь мы также обсудим введение и синтаксис sql select top вместе с различными примерами и реализацией кода. Вы также можете ознакомиться со следующими статьями, чтобы узнать больше:

  1. MySQL CEIL
  2. Виртуальная таблица SQL
  3. Синхронизация MySQL
  4. Сопоставление шаблонов SQL

SQL Select Top

В этом разделе мы описали Select Top с подробным примером.

При работе с большим количеством строк в таблице мы можем получить несколько строк в наборе результатов. Если мы хотим получить только определенные строки, мы можем использовать оператор SELECT TOP. Используя оператор SELECT TOP, мы можем получить столько строк из набора результатов, сколько нужно.

Синтаксис —
 SELECT TOP Number| Процент Столбец1, Столбец2,..
 FROM Имя_таблицы [WHERE Condition];
 

Пример —

Давайте рассмотрим приведенную ниже таблицу (таблицы) в качестве примера таблицы (таблиц) для создания SQL-запроса для получения желаемых результатов.

employee_details —
emp_id emp_name обозначение manager_id date_of_hire зарплата dept_id
001 Сотрудник1 Директор 11.07.2019 45000.00 1000
002 Сотрудник2 Директор 11. 07.2019 40000,00 2000
003 Сотрудник3 Менеджер Сотрудник1 11.07.2019 27000.00 1000
004 Сотрудник4 Менеджер Сотрудник2 08.10.2019 25000,00 2000
005 Сотрудник5 Аналитик Сотрудник3 11.07.2019 20000.00 1000
006 Сотрудник6 Аналитик Сотрудник3 08.10.2019 18000.00 1000
007 Сотрудник7 Клерк Сотрудник3 11.07.2019 15000.00 1000
008 Сотрудник8 Продавец Сотрудник4 2019—09-09 14000.00 2000
009 Сотрудник9 Продавец Сотрудник4 08. 10.2019 13000.00 2000

Сценарий – Получение указанных строк из таблицы.

Требование — Получить первые 4 строки из таблицы employee_details. Запрос был следующим —

 SELECT TOP 4 * FROM employee_details;
 

Выполнив вышеуказанный запрос, мы можем получить первые 4 строки из таблицы employee_details. Результат был таким, как показано ниже:

.
emp_id emp_name обозначение manager_id date_of_hire зарплата dept_id
001 Сотрудник1 Директор 11.07.2019 45000.00 1000
002 Сотрудник2 Директор 11.07.2019 40000,00 2000
003 Сотрудник3 Менеджер Сотрудник1 11. 07.2019 27000.00 1000
004 Сотрудник4 Менеджер Сотрудник2 08.10.2019 25000,00 2000

Сценарий — Получить указанные строки с указанными столбцами из таблицы.

Требование — Получить emp_id, emp_name, обозначение первых четырех строк из таблицы employee_details. Запрос был такой —

 ВЫБЕРИТЕ ПЕРВЫЕ 4 emp_id, emp_name, назначение ИЗ employee_details;
 

Выполнив вышеуказанный запрос, мы можем получить первые 4 строки с указанными столбцами из таблицы employee_details. Результат был таким, как показано ниже:

.
emp_id emp_name обозначение
001 Сотрудник1 Директор
002 Сотрудник2 Директор
003 Сотрудник3 Менеджер
004 Сотрудник4 Менеджер

Сценарий — Получить указанные процентные строки из таблицы.

Требование — Получить первые 50% от общего числа строк из таблицы employee_details. Запрос был следующим:

 ВЫБЕРИТЕ ВЕРХНИЕ 50 ПРОЦЕНТОВ * ОТ employee_details;
 

Выполнив вышеуказанный запрос, мы можем получить первые 50% строк из таблицы employee_details. Результат был таким, как показано ниже —

emp_id emp_name обозначение manager_id date_of_hire зарплата dept_id
001 Сотрудник1 Директор 11.07.2019 45000.00 1000
002 Сотрудник2 Директор 11.07.2019 40000,00 2000
003 Сотрудник3 Менеджер Сотрудник1 11.07.2019 27000.00 1000
004 Сотрудник4 Менеджер Сотрудник2 08. 10.2019 25000,00 2000
005 Сотрудник5 Аналитик Сотрудник3 11.07.2019 20000.00 1000

Сценарий — Получить указанные процентные строки с указанными столбцами из таблицы.

Требование — Получить столбцы emp_id, emp_name, обозначение из первых 50% от общего числа строк в таблице employee_details. Запрос был следующим —

 SELECT TOP 50 PERCENT emp_id, emp_name, обозначение
ОТ employee_details;
 

Выполнив вышеуказанный запрос, мы можем получить 50 процентов строк указанных столбцов из таблицы employee_details. Результат был таким, как показано ниже:

.
emp_id emp_name обозначение
001 Сотрудник1 Директор
002 Сотрудник2 Директор
003 Сотрудник3 Менеджер
004 Сотрудник4 Менеджер
005 Сотрудник5 Аналитик

Сценарий — Получить указанные процентные строки с указанными столбцами с предложением WHERE.

Требование — Получить 50% строк emp_id, emp_name, сведения о назначении из таблицы employee_details из отдела 1000. Запрос был следующим —

 SELECT TOP 50 PERCENT emp_id, emp_name, обозначение
ОТ employee_details ГДЕ dept_id = 1000;
 

Выполнив вышеуказанный запрос, мы можем получить 50 процентов строк из таблицы employee_details под dept_id 1000. Вывод был таким, как показано ниже:

emp_id emp_name обозначение
001 Сотрудник1 Директор
003 Сотрудник3 Менеджер
005 Сотрудник5 Аналитик

Сценарий — Получить указанные строки с указанными столбцами из таблицы с помощью предложения WHERE.

Требование — Получить первые 2 emp_id, emp_name, сведения о назначении из таблицы employee_details из отдела 2000. Запрос был следующим —

 SELECT TOP 2 emp_id, emp_name, обозначение
ОТ employee_details ГДЕ dept_id = 2000;
 

Выполнив вышеуказанный запрос, мы можем получить первые 2 строки с emp_id, emp_name, сведениями о назначении из таблицы employee_details, принадлежащей dept_id 2000.

Оставить комментарий

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *