Разное

Fetch sql: FETCH ОПЕРАТОР — Oracle PL/SQL •MySQL •MariaDB •SQL Server •SQLite

Содержание

FETCH ОПЕРАТОР — Oracle PL/SQL •MySQL •MariaDB •SQL Server •SQLite

В этом учебном материале вы узнаете, как использовать оператор FETCH в Oracle/PLSQL c синтаксисом и примерами.

Описание

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

Синтаксис

FETCH имя_курсора INTO variable_list;

Параметры или аргументы
имя_курсора наименование курсора, из которого вы хотите извлечь строки.
variable_list список переменных, разделенных запятыми, в которые вы хотите сохранить результирующий набор курсора.

Пример

Определим курсор таким образом.

CURSOR c1
IS
SELECT course_number
FROM courses_tbl
WHERE course_name = name_in;

CURSOR c1

IS

   SELECT course_number

   FROM courses_tbl

   WHERE course_name = name_in;

Команда, которая будет использоваться для выборки данных из этого курсор:

FETCH c1 into cnumber;

Эта команда выберет первое course_number в переменную cnumber.
Далее функция, которая показывает, как использовать оператор FETCH.

CREATE OR REPLACE Function FindCourse
( name_in IN varchar2 )
RETURN number
IS
cnumber number;
CURSOR c1
IS
SELECT course_number
FROM courses_tbl
WHERE course_name = name_in;

BEGIN

OPEN c1;
FETCH c1 INTO cnumber;

if c1%notfound then
cnumber := 9999;
end if;

CLOSE c1;
RETURN cnumber;
END;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

CREATE OR REPLACE Function FindCourse

   ( name_in IN varchar2 )

   RETURN number

IS

   cnumber number;

   CURSOR c1

   IS

     SELECT course_number

     FROM courses_tbl

     WHERE course_name = name_in;

 

BEGIN

 

   OPEN c1;

   FETCH c1 INTO cnumber;

 

   if c1%notfound then

      cnumber := 9999;

   end if;

 

   CLOSE c1;

RETURN cnumber;

END;

Инструкция FETCH — SQL программирование

Инструкция FETCH — это одна из четырех команд, используемых при обработке курсоров, наряду с DECLARE, OPEN и CLOSE. Курсоры позволяют вести обработку по одной строке, а не работать сразу со всем набором. Инструкция FETCH помещает курсор в конкретную строку и извлекает эту строку из результирующего набора.

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

Синтаксис SQL 2003

SQL 2003 Syntax

FETCH [{NEXT | PRIOR | FIRST | LAST |

{ABSOLUTE | RELATIVE int}}

FROM] имя_курсора [INTO переменная 1 [, …]]

Ключевые слова

NEXT

Указывается, что курсор должен вернуть запись, которая идет сразу за текущей, и сделать текущей ту запись, которую курсор вернул. Предложение FETCH NEXT задано для инструкции FETCH по умолчанию. При этом первая запись извлекается, если инструкция FETCH осуществляет первую выборку для курсора.

PRIOR

Указывается, что курсор должен вернуть запись, которая идет непосредственно перед текущей, и сделать текущей ту запись, которую курсор вернул. Инструкция FETCH PRIOR не возвращает запись, если она осуществляет первую выборку для курсора.

FIRST

Указывается, что курсор должен вернуть запись, которая является для курсора первой, и сделать ее текущей.

LAST

Указывается, что курсор должен вернуть запись, которая является для курсора последней, и сделать ее текущей.

ABSOLUTE int

Указывается, что курсор должен вернуть запись, которая имеет номер int в наборе записей курсора, считая сверху (если int — положительное целое число) или считая снизу (если int — отрицательное целое число), и сделать эту запись текущей для курсора. Если int ~ О, строка не возвращается. Если значение int переносит курсор за пределы набора, тогда курсор устанавливается после последней строки (если int -положительное число) или перед первой строкой (если int — отрицательное число).

RELATIVE int

Указывается, что курсор должен вернуть запись, идущую через int записей после текущей (если int — положительное число) или через int записей перед текущей (если int — отрицательное число). Если int= О, возвращается текущая строка. Если значение int переносит курсор за пределы набора, тогда курсор устанавливается после последней строки (если int — положительное число) или перед первой строкой (если int — отрицательное число).

[FROM] имя_курсора

Указывается имя открытого курсора, из которого вы хотите извлечь строки. Курсор должен быть заранее определен и создан при помощи предложений DECLARE и OPEN: Использование ключевого слова FROM является необязательным, но поощряется.

INTO переменная! [, …]

Данные из каждого столбца курсора сохраняются в локальной переменной. Каждый столбец курсора должен иметь в предложении INTO соответствующую переменную совпадающего типа данных. Каждое значение в столбце напрямую связано с переменными в соответствующих порядковых положениях.

Postgres Pro Standard : Документация: 10: FETCH : Компания Postgres Professional

FETCH

FETCH — получить результат запроса через курсор

Синтаксис

FETCH [ direction [ FROM | IN ] ] имя_курсора

Здесь direction может быть пустым или принимать следующее значение:

    NEXT
    PRIOR
    FIRST
    LAST
    ABSOLUTE число
    RELATIVE число
    число
    ALL
    FORWARD
    FORWARD число
    FORWARD ALL
    BACKWARD
    BACKWARD число
    BACKWARD ALL

Описание

FETCH получает строки через ранее созданный курсор.

Курсор связан с определённым положением, что и использует команда FETCH. Курсор может располагаться перед первой строкой результата запроса, на любой строке этого результата, либо после последней строки. При создании курсор оказывается перед первой строкой. Когда FETCH доходит до конца набора строк, курсор остаётся в положении после последней строки, либо перед первой, при движении назад. После команд FETCH ALL и FETCH BACKWARD ALL курсор всегда оказывается после последней строки или перед первой, соответственно.

Формы NEXT, PRIOR, FIRST, LAST, ABSOLUTE и RELATIVE выбирают одну строку после соответствущего перемещения курсора. Если в этом положении строки не оказывается, возвращается пустой результат, а курсор остаётся в достигнутом положении перед первой строкой или после последней.

Формы FORWARD и BACKWARD получают указанное число строк, сдвигаясь соответственно вперёд или назад; в результате курсор оказывается на последней выданной строке (или перед/после всех строк, если число превышает количество доступных строк).

Формы RELATIVE 0, FORWARD 0 и BACKWARD 0 действуют одинаково — они считывают текущую строку, не перемещая курсор, то есть, повторно выбирая строку, выбранную последней. Эта операция будет успешна, только если курсор не расположен до первой или после последней строки; в этом случае строка возвращена не будет.

Примечание

На этой странице описывается применение курсоров на уровне команд SQL. Если вы попытаетесь использовать курсоры внутри функции PL/pgSQL, правила будут другими — см. Подраздел 41.7.3.

Параметры

direction

Параметр направление задаёт направление движения и число выбираемых строк. Он может принимать одно из следующих значений:

NEXT

Выбрать следующую строку. Это действие подразумевается по умолчанию, если направление опущено.

PRIOR

Выбрать предыдущую строку.

FIRST

Выбрать первую строку запроса (аналогично указанию ABSOLUTE 1).

LAST

Выбрать последнюю строку запроса (аналогично ABSOLUTE -1).

ABSOLUTE число

Выбрать строку под номером число с начала, либо под номером abs(число) с конца, если число отрицательно. Если число выходит за границы набора строк, курсор размещается перед первой или после последней строки; в частности, с ABSOLUTE 0 курсор оказывается перед первой строкой.

RELATIVE число

Выбрать строку под номером число, считая со следующей вперёд, либо под номером abs(число), считая с предыдущей назад, если число отрицательно. RELATIVE 0 повторно считывает текущую строку, если таковая имеется.

число

Выбрать следующее число строк (аналогично FORWARD число).

ALL

Выбрать все оставшиеся строки (аналогично FORWARD ALL).

FORWARD

Выбрать следующую строку (аналогично NEXT).

FORWARD число

Выбрать следующее число строк. FORWARD 0 повторно выбирает текущую строку.

FORWARD ALL

Выбрать все оставшиеся строки.

BACKWARD

Выбрать предыдущую строку (аналогично PRIOR).

BACKWARD число

Выбрать предыдущее число строк (с перемещением назад). BACKWARD 0 повторно выбирает текущую строку.

BACKWARD ALL

Выбрать все предыдущие строки (с перемещением назад).

число

Здесь число — целочисленная константа, возможно со знаком, определяющая смещение или количество выбираемых строк. Для вариантов FORWARD и BACKWARD указание отрицательного числа равнозначно смене направления FORWARD на BACKWARD и наоборот.

имя_курсора

Имя открытого курсора.

Выводимая информация

При успешном выполнении FETCH возвращает метку команды вида

FETCH число

Здесь count — количество выбранных строк (может быть и нулевым). Заметьте, что в psql метка команды не выдаётся, так как вместо неё psql выводит выбранные строки.

Замечания

Если перемещение курсора в FETCH не ограничивается вариантами FETCH NEXT или FETCH FORWARD с положительным числом, курсор должен быть объявлен с указанием SCROLL. Для простых запросов Postgres Pro допускает обратное перемещение курсора, объявленного без SCROLL, но на это поведение лучше не рассчитывать. Если курсор объявлен с указанием NO SCROLL, перемещение назад запрещается.

Вариант ABSOLUTE нисколько не быстрее, чем перемещение к требуемой строке с относительным сдвигом: нижележащий механизм всё равно должен прочитать все промежуточные строки. Выборки по абсолютному отрицательному положению ещё хуже: сначала запрос необходимо прочитать до конца и найти последнюю строку, а затем вернуться назад к указанной строке. Однако перемотка к началу запроса (FETCH ABSOLUTE 0) выполняется быстро.

Определить курсор позволяет команда DECLARE, а переместить его, не читая данные, — команда MOVE.

Примеры

Следующий пример демонстрирует перемещение курсора в таблице:

BEGIN WORK;

-- Создание курсора:
DECLARE liahona SCROLL CURSOR FOR SELECT * FROM films;

-- Получение первых 5 строк через курсор liahona:
FETCH FORWARD 5 FROM liahona;

 code  |          title          | did | date_prod  |   kind   |  len
-------+-------------------------+-----+------------+----------+-------
 BL101 | The Third Man           | 101 | 1949-12-23 | Drama    | 01:44
 BL102 | The African Queen       | 101 | 1951-08-11 | Romantic | 01:43
 JL201 | Une Femme est une Femme | 102 | 1961-03-12 | Romantic | 01:25
 P_301 | Vertigo                 | 103 | 1958-11-14 | Action   | 02:08
 P_302 | Becket                  | 103 | 1964-02-03 | Drama    | 02:28

-- Получение предыдущей строки:
FETCH PRIOR FROM liahona;

 code  |  title  | did | date_prod  |  kind  |  len
-------+---------+-----+------------+--------+-------
 P_301 | Vertigo | 103 | 1958-11-14 | Action | 02:08

-- Закрытие курсора и завершение транзакции:
CLOSE liahona;
COMMIT WORK;

Совместимость

В стандарте SQL команда FETCH определена только для встраиваемого SQL. Описанная здесь реализация FETCH возвращает данные подобно оператору SELECT, а не помещает их в переменные исполняющей среды. В остальном, FETCH полностью прямо-совместима со стандартом SQL.

Формы FETCH с FORWARD и BACKWARD, а также формы FETCH число и FETCH ALL (в которых FORWARD подразумевается) являются расширениями Postgres Pro.

В стандарте SQL перед именем курсора допускается только указание FROM; возможность указать IN или опустить оба указания относится к расширениям.

FETCH оператор MySQL — Oracle PL/SQL •MySQL •MariaDB •SQL Server •SQLite

В этом учебном пособии вы узнаете, как в MySQL использовать оператор FETCH для извлечения следующей строки для курсора с синтаксисом и примерами.

Описание

Цель использования курсора в большинстве случаев заключается в том, чтобы извлекать строки из вашего курсора, чтобы можно было выполнить какие-либо операции над данными. После объявления и открытия курсора следующим шагом будет использование инструкции FETCH для извлечения строк из вашего курсора.

Синтаксис

Синтаксис оператора FETCH в MySQL:

FETCH [ NEXT [ FROM ] ] cursor_name INTO variable_list;

Параметры или аргументы

cursor_name – наименование курсора, строки которого вы хотите получить.
variable_list — список переменных, разделенных запятыми, в которые вы хотите сохранить результирующий набор курсора.

Пример

Рассмотрим, как получить следующую строку для курсора, используя оператор FETCH в MySQL.
Например, вы могли бы иметь курсор, определенный в MySQL, следующим образом:

DECLARE cr1 CURSOR FOR
SELECT site_id
FROM sites
WHERE site_name = name_in;

DECLARE cr1 CURSOR FOR

  SELECT site_id

  FROM sites

  WHERE site_name = name_in;

Команда, которая будет использоваться для извлечения данных из этого курсора:

Это позволит получить первое значение site_id в переменной site_ID.
Ниже приведена функция, демонстрирующая, как использовать оператор FETCH.

DELIMITER //

CREATE FUNCTION FindSiteID ( name_in VARCHAR(50) )
RETURNS INT

BEGIN

DECLARE done INT DEFAULT FALSE;
DECLARE siteID INT DEFAULT 0;

DECLARE cr1 CURSOR FOR
SELECT site_id
FROM sites
WHERE site_name = name_in;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

OPEN cr1;
FETCH cr1 INTO siteID;

CLOSE cr1;

RETURN siteID;

END; //

DELIMITER ;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

DELIMITER //

 

CREATE FUNCTION FindSiteID ( name_in VARCHAR(50) )

RETURNS INT

 

BEGIN

 

   DECLARE done INT DEFAULT FALSE;

   DECLARE siteID INT DEFAULT 0;

 

   DECLARE cr1 CURSOR FOR

     SELECT site_id

     FROM sites

     WHERE site_name = name_in;

 

   DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

 

   OPEN cr1;

   FETCH cr1 INTO siteID;

 

   CLOSE cr1;

 

   RETURN siteID;

 

END; //

 

DELIMITER ;

Postgres Pro Standard : Документация: 9.6: FETCH : Компания Postgres Professional

FETCH

FETCH — получить результат запроса через курсор

Синтаксис

FETCH [ direction [ FROM | IN ] ] имя_курсора

Здесь direction может быть пустым или принимать следующее значение:

    NEXT
    PRIOR
    FIRST
    LAST
    ABSOLUTE число
    RELATIVE число
    число
    ALL
    FORWARD
    FORWARD число
    FORWARD ALL
    BACKWARD
    BACKWARD число
    BACKWARD ALL

Описание

FETCH получает строки через ранее созданный курсор.

Курсор связан с определённым положением, что и использует команда FETCH. Курсор может располагаться перед первой строкой результата запроса, на любой строке этого результата, либо после последней строки. При создании курсор оказывается перед первой строкой. Когда FETCH доходит до конца набора строк, курсор остаётся в положении после последней строки, либо перед первой, при движении назад. После команд FETCH ALL и FETCH BACKWARD ALL курсор всегда оказывается после последней строки или перед первой, соответственно.

Формы NEXT, PRIOR, FIRST, LAST, ABSOLUTE и RELATIVE выбирают одну строку после соответствущего перемещения курсора. Если в этом положении строки не оказывается, возвращается пустой результат, а курсор остаётся в достигнутом положении перед первой строкой или после последней.

Формы FORWARD и BACKWARD получают указанное число строк, сдвигаясь соответственно вперёд или назад; в результате курсор оказывается на последней выданной строке (или перед/после всех строк, если число превышает количество доступных строк).

Формы RELATIVE 0, FORWARD 0 и BACKWARD 0 действуют одинаково — они считывают текущую строку, не перемещая курсор, то есть, повторно выбирая строку, выбранную последней. Эта операция будет успешна, только если курсор не расположен до первой или после последней строки; в этом случае строка возвращена не будет.

Примечание

На этой странице описывается применение курсоров на уровне команд SQL. Если вы попытаетесь использовать курсоры внутри функции PL/pgSQL, правила будут другими — см. Подраздел 40.7.3.

Параметры

direction

Параметр направление задаёт направление движения и число выбираемых строк. Он может принимать одно из следующих значений:

NEXT

Выбрать следующую строку. Это действие подразумевается по умолчанию, если направление опущено.

PRIOR

Выбрать предыдущую строку.

FIRST

Выбрать первую строку запроса (аналогично указанию ABSOLUTE 1).

LAST

Выбрать последнюю строку запроса (аналогично ABSOLUTE -1).

ABSOLUTE число

Выбрать строку под номером число с начала, либо под номером abs(число) с конца, если число отрицательно. Если число выходит за границы набора строк, курсор размещается перед первой или после последней строки; в частности, с ABSOLUTE 0 курсор оказывается перед первой строкой.

RELATIVE число

Выбрать строку под номером число, считая со следующей вперёд, либо под номером abs(число), считая с предыдущей назад, если число отрицательно. RELATIVE 0 повторно считывает текущую строку, если таковая имеется.

число

Выбрать следующее число строк (аналогично FORWARD число).

ALL

Выбрать все оставшиеся строки (аналогично FORWARD ALL).

FORWARD

Выбрать следующую строку (аналогично NEXT).

FORWARD число

Выбрать следующее число строк. FORWARD 0 повторно выбирает текущую строку.

FORWARD ALL

Выбрать все оставшиеся строки.

BACKWARD

Выбрать предыдущую строку (аналогично PRIOR).

BACKWARD число

Выбрать предыдущее число строк (с перемещением назад). BACKWARD 0 повторно выбирает текущую строку.

BACKWARD ALL

Выбрать все предыдущие строки (с перемещением назад).

число

Здесь число — целочисленная константа, возможно со знаком, определяющая смещение или количество выбираемых строк. Для вариантов FORWARD и BACKWARD указание отрицательного числа равнозначно смене направления FORWARD на BACKWARD и наоборот.

имя_курсора

Имя открытого курсора.

Выводимая информация

При успешном выполнении FETCH возвращает метку команды вида

FETCH число

Здесь count — количество выбранных строк (может быть и нулевым). Заметьте, что в psql метка команды не выдаётся, так как вместо неё psql выводит выбранные строки.

Замечания

Если перемещение курсора в FETCH не ограничивается вариантами FETCH NEXT или FETCH FORWARD с положительным числом, курсор должен быть объявлен с указанием SCROLL. Для простых запросов Postgres Pro допускает обратное перемещение курсора, объявленного без SCROLL, но на это поведение лучше не рассчитывать. Если курсор объявлен с указанием NO SCROLL, перемещение назад запрещается.

Вариант ABSOLUTE нисколько не быстрее, чем перемещение к требуемой строке с относительным сдвигом: нижележащий механизм всё равно должен прочитать все промежуточные строки. Выборки по абсолютному отрицательному положению ещё хуже: сначала запрос необходимо прочитать до конца и найти последнюю строку, а затем вернуться назад к указанной строке. Однако перемотка к началу запроса (FETCH ABSOLUTE 0) выполняется быстро.

Определить курсор позволяет команда DECLARE, а переместить его, не читая данные, — команда MOVE.

Примеры

Следующий пример демонстрирует перемещение курсора в таблице:

BEGIN WORK;

-- Создание курсора:
DECLARE liahona SCROLL CURSOR FOR SELECT * FROM films;

-- Получение первых 5 строк через курсор liahona:
FETCH FORWARD 5 FROM liahona;

 code  |          title          | did | date_prod  |   kind   |  len
-------+-------------------------+-----+------------+----------+-------
 BL101 | The Third Man           | 101 | 1949-12-23 | Drama    | 01:44
 BL102 | The African Queen       | 101 | 1951-08-11 | Romantic | 01:43
 JL201 | Une Femme est une Femme | 102 | 1961-03-12 | Romantic | 01:25
 P_301 | Vertigo                 | 103 | 1958-11-14 | Action   | 02:08
 P_302 | Becket                  | 103 | 1964-02-03 | Drama    | 02:28

-- Получение предыдущей строки:
FETCH PRIOR FROM liahona;

 code  |  title  | did | date_prod  |  kind  |  len
-------+---------+-----+------------+--------+-------
 P_301 | Vertigo | 103 | 1958-11-14 | Action | 02:08

-- Закрытие курсора и завершение транзакции:
CLOSE liahona;
COMMIT WORK;

Совместимость

В стандарте SQL команда FETCH определена только для встраиваемого SQL. Описанная здесь реализация FETCH возвращает данные подобно оператору SELECT, а не помещает их в переменные исполняющей среды. В остальном, FETCH полностью прямо-совместима со стандартом SQL.

Формы FETCH с FORWARD и BACKWARD, а также формы FETCH число и FETCH ALL (в которых FORWARD подразумевается) являются расширениями Postgres Pro.

В стандарте SQL перед именем курсора допускается только указание FROM; возможность указать IN или опустить оба указания относится к расширениям.

MS SQL 2011 – новый оператор Offset / Хабр

В новом SQL Server 2011 (Denali) расширяются возможности команды Order By с помощью двух долгожданных дополнительных команд:

  • Offset (смещение)
  • Fetch First или Fetch Next (взять первые… или взять следующие…)

Offset

Использование данной команды позволяет пропустить указанное количество строк перед тем как выводить результаты запроса. Что под этим подразумевается: Допустим, у нас есть 100 записей в таблице и нужно пропустить первые 10 строк и вывести строки с 11 по 100. Теперь это легко решается следующим запросом:

Select *
From  <SomeTable>
Order by  <SomeColumn>
Offset 10 Rows

Для тех товарищей, которые практикуют .Net должен быть знаком метод расширения для коллекций Skip, который пропускает указанное количество строк. Так вот выражение Offset работает точно так же. После того как данные упорядочены каким-либо образом, можно применять выражение Offset.

Ситуации, в которых может быть использовано выражение Offset

Во всех последующих примерах на Offset будет использовать набор данных построенных в результате данного скрипта:

-- объявление табличной переменной
Declare @tblSample Table
(
	 [Person Name] Varchar(50)
	,Age int
	,Address Varchar(100)
)

-- заполнение данными
Insert into @tblSample
Select
	 'Person Name' + CAST(Number AS VARCHAR)
	, Number
	,'Address' + CAST(Number AS VARCHAR)
From master..spt_values
Where Type = 'p'
And Number Between 1 and 50

Задача 1. Пропустить первые 10 записей и показать остальные.

Скрипт будет простой.

Select *
From @tblSample
Order by Age
Offset 10 Row

Или

Select *
From @tblSample
Order by Age
Offset (10) Rows

Вывод результатов будет таким:

Person Name      Age      Address
Person Name11    11       Address11
Person Name12    12       Address12
. . . . .  . . . . . . . . .
. . . . . .. . . . . . . . .
Person Name49    49       Address49
Person Name50    50       Address50

Неважно, какое слово использовать после указания количества строк: Row или Rows – они синонимы в данном случае.

Задача 2. Передать количество строк для пропуска в виде переменной

-- Объявляем переменную в которой будет содержаться кол-во строк для пропуска
Declare @RowSkip As int
-- Выставляем количество строк для пропуска
Set @RowSkip = 10

-- получаем результат
Select *
From @tblSample
Order by Age
Offset @RowSkip Row

Задача 3. Задать количество строк для пропуска в виде выражения

-- получить строки с 14 по 50
Select *
From @tblSample
Order by Age
Offset (select MAX(number)/99999999 from  master..spt_values) Rows

Выражение select MAX(number)/99999999 from master..spt_values вернет число 14.

Задача 4. Задать количество строк для пропуска в виде пользовательской функции

Select *
From @tblSample
Order by Age
Offset (select dbo.fn_test()) Rows

Код для скалярной пользовательской функции

CREATE FUNCTION fn_test()
RETURNS int
AS
BEGIN
Declare @ResultVar as int

Select @ResultVar = 10

RETURN @ResultVar
END
GO

Задача 5. Использование Offset с Order by внутри представлений (view), функций, подзапросах, вложенных таблицах, общих выражениях для таблиц (Common Table Expressions — CTE).

Например, использование в общих выражениях.

;With Cte As
(
	Select *
	From @tblSample
	Order By Age
	Offset 10 Rows)

Select *
From Cte

Пример ниже показывает использование Offset и Order by внутри вложенной таблицы.

Select *
From
	(Select *
	 From @tblSample
	 Where Age >10
	 Order By Age
	 Offset 10 Rows) As PersonDerivedTable

И еще пример на работу Offset и Order с представлениями.

-- Создание view
Create View vwPersonRecord AS
Select * FROM tblSample
GO

-- выборка данных из view
Select *
From vwPersonRecord
Where Age > 10
Order By Age
Offset 10 Rows

Когда Offset не будет работать

1.  Так как это «метод расширения», то без выражения order by ничего работать не будет.

Select *
From @tblSample
Offset (10) Rows

Сообщит об ошибке

Msg 102, Level 15, State 1, Line 21 Incorrect syntax near ’10’.

2.  Нельзя задавать отрицательное значение для Offset.

Select *
From @tblSample
Order by Age
Offset (-10) Rows

Движок SQL сервера выдаст

Msg 10742, Level 15, State 1, Line 22 The offset specified in a OFFSET clause may not be negative.

3.  Нельзя задавать значения отличные от целочисленного типа.

Select *
From @tblSample
Order by Age
Offset 10.5 Rows

или

Select *
From @tblSample
Order by Age
Offset Null Rows

Выдаст нам

Msg 10743, Level 15, State 1, Line 24 The number of rows provided for a OFFSET clause must be an integer.

4.  Не может быть использован внутри выражения Over().

;With Cte As
(
	Select
		*,
		Rn = Row_Number() Over(Order by Age Offset 10 Rows)
	From @tblSample
)

Select * from Cte

Во время выполнения запроса получим сообщение

Msg 102, Level 15, State 1, Line 22 Incorrect syntax near ‘Offset’.

Использование Fetch First / Fetch Next

Эти ключевые слова используются для уточнения количества возвращаемых строк после пропуска массива строк по выражению Offset. Представьте, что у нас есть 100 строк и нам надо пропустить первые 10 и получить следующие 5 строк. Т.е. надо получить строки с 11 по 15.

Select *
From  <SomeTable>
Order by  <SomeColumn>
Offset 10 Rows
Fetch Next 5 Rows Only; -- или Fetch First 5 Rows Only

Такой запрос вернет ожидаемое кол-во строк. Программисты на .Net тут же припомнят метод расширения Take.

Далее рассмотрим ситуации, где можно применить эти ключевые слова.

Задача 1. Пропустить первые 10 записей и получить следующие 5

Select *
From @tblSample
Order by Age
Offset 10 Row
Fetch First 5 Rows Only

Результат будет таким:

Person Name      Age      Address
Person Name11    11       Address11
Person Name12    12       Address12
Person Name13    13       Address13
Person Name14    14       Address14
Person Name15    15       Address15

Задача 2. Задать количество строк для вывода с помощью переменной

-- переменная для указания смещения
Declare @RowSkip As int
-- переменная для указания кол-ва возвращаемых строк
Declare @RowFetch As int

-- кол-во строк для пропуска
Set @RowSkip = 10
-- кол-во строк для возврата
Set @RowFetch = 5

-- вывод строк с 11 по 15
Select *
From @tblSample
Order by Age
Offset @RowSkip Row
Fetch  Next @RowFetch Rows Only;

В целом и общем, с этими ключевыми словами можно делать все то же самое, что и с Offset. Подзапросы, представления, функции и т.д.

Когда Fetch First / Fetch Next не будут работать

Ограничения на эти ключевые слова полностью совпадают с ограничениями на Offset.

Симуляция Offset и Fetch Next для Sql Server 2005/2008

В предыдущих версиях SQL сервера можно было получить тот же функционал путем применения функции ранжирования Row_Number(). Конечно код получался не такой изящный и лаконичный, например:

-- Переменная для указания строк смещения
Declare @RowSkip As int
-- Переменная для указания кол-ва строк для возврата
Declare @RowFetch As int

-- Задание переменных
Set @RowSkip = 10
Set @RowFetch = 5

;With Cte As
(
	Select
		rn=ROW_NUMBER()
		Over(Order by (Select 1) /* генерируем служебную колонку */ )
		,*
	From @tblSample
)
-- забираем записи с 11 по 15
Select
	[Person Name]
	,Age
	,Address
From Cte

-- симуляция поведения Offset и Fetch First/Fetch Next
Where rn Between  (@RowSkip+1) -- симуляция Offset
	And  (@RowSkip+ @RowFetch) -- симуляция Fetch First/Fetch Next Clause

Внутри CTE идет генерация служебной колонки которая просто нумерует строки, после чего строки фильтруются по этому полю. Способ не самый быстрый как вы понимаете.

Симуляция Offset и Fetch Next для Sql Server 2000

Для этих древних серверов не было функций ранжирования, но и тогда можно было повторить обсуждаемый функционал. Тогда в ход шли временные таблицы с авто инкрементальным полем. Пример скрипта:

Declare @RowSkip As int
Declare @RowFetch As int

Set @RowSkip = 10
Set @RowFetch = 5

--если временная таблица существует, то удалить ее
IF OBJECT_ID('tempdb..#Temp') IS NOT NULL
BEGIN
	Drop Table #Temp
END

--создание временной таблицы
Create Table #Temp
(
	 Rn int Identity
	,[Person Name] Varchar(50)
	,Age int
	,Address Varchar(100)
)

-- заполнение временной таблицы
Insert Into #Temp([Person Name],Age,Address)
Select  [Person Name],Age,Address
From @tblSample

-- получение строк с 11 по 15
Select
	 [Person Name]
	,Age
	,Address
From #Temp

-- симуляция поведения Offset и Fetch First/Fetch Next
Where Rn Between  (@RowSkip+1) -- симуляция Offset
	And  (@RowSkip+ @RowFetch) -- симуляция Fetch First/Fetch Next

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

Практическое применение Offset и Fetch с замерами времени и ресурсов

Я уверен, что всё предыдущее объяснение об использовании и назначении Offset и Fetch подвело вас к ясному пониманию, зачем они нужны и где их можно использовать. Родились идеи по оптимизации существующего кода. Далее мы рассмотрим пример из реальной практики, когда может пригодиться Offset. Так же будут приведены результаты замеров производительности на разных SQL серверах. Тесты будут прогоняться на выборке из 1 миллиона строк.

Для начала создадим счет-таблицу по следующему скрипту.

-- удалить таблицу tblSample, если она существует
IF OBJECT_ID('tblSample','U') IS NOT NULL BEGIN
	DROP TABLE tblSample
END
GO

-- создать таблицу
Create Table tblSample (
	 [Person ID]      Int Identity
	,[Person Name] Varchar(100)
	,Age Int
	,DOB Datetime
	,Address Varchar(100)
)
GO

-- заполнить таблицу миллионом записей
Insert into tblSample
Select
	'Person Name' + CAST(N AS VARCHAR)
	, N
	,DATEADD(D,N, '1900-01-01')
	,'Address' + CAST(N AS VARCHAR)
From dbo.tsqlc_Tally
Where  N Between 1 and 1000000

-- вывести данные
Select *
From tblSample

Постраничный просмотр данных на стороне сервера

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

В целях эксперимента мы пропустим первые 20 000 записей и возьмем следующие 50 000.

Подход для SQL Server 2000
-- сброс буфера и кэша статистики
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE

USE TSQLDB;
GO

SET STATISTICS IO ON;
SET STATISTICS TIME ON;
GO

-- Переменные для пэйджинга
Declare @RowSkip As int
Declare @RowFetch As int

-- Установка значений постраничного просмотра
Set @RowSkip = 20000
Set @RowFetch = 50000

--Удаление временной таблицы, если она есть
IF OBJECT_ID('tempdb..#Temp') IS NOT NULL
BEGIN
	Drop Table #Temp
END

-- создание временной таблицы
Create Table #Temp
(
	 Rn int Identity
	,[Person ID] int
	,[Person Name] Varchar(50)
	,Age int
	,DOB datetime
	,Address Varchar(100)
)

-- Занесение данных во временную таблицу
Insert Into #Temp([Person ID],[Person Name],Age,DOB,Address)
Select  [Person ID],[Person Name],Age,DOB,Address
From dbo.tblSample

-- выборка данных с 20 000 по 70 000
Select
	 [Person ID]
	,[Person Name]
	,Age
	,DOB
	,Address
From #Temp

-- симуляция поведения Offset и Fetch First/Fetch Next
Where Rn Between  (@RowSkip+1) -- симуляция Offset
	And  (@RowSkip+ @RowFetch) -- симуляция Fetch First/Fetch Next

GO

SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;
GO

Я думаю что предыдущих примеров и комментариев хватает, чтобы понять работу скрипта.

Время выполнения:

SQL Server Execution Times:

CPU time = 110 ms,  elapsed time = 839 ms.

Статистика ввода\вывода:

Scan count 1,

logical reads 8037,

physical reads 0,

read-ahead reads 0,

lob logical reads 0,

lob physical reads 0,

lob read-ahead reads 0.

Подход для SQL Server 2005/2008
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE

USE TSQLDB;
GO

SET STATISTICS IO ON;
SET STATISTICS TIME ON;
GO

Declare @RowSkip As int
Declare @RowFetch As int

Set @RowSkip = 20000
Set @RowFetch = 50000

;With Cte As
(
	Select
		rn=ROW_NUMBER()
		Over(Order by (Select 1))
		,*
	From dbo.tblSample

)

Select
	 [Person ID]
	,[Person Name]
	,Age
	,DOB
	,Address
From Cte

Where rn Between  (@RowSkip+1) <em> </em>
	And  (@RowSkip+ @RowFetch)

GO

SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;
GO

 

Время выполнения:

SQL Server Execution Times:

CPU time = 78 ms,  elapsed time = 631 ms.

Статистика ввода\вывода:

Scan count 1,

logical reads 530,

physical reads 0,

read-ahead reads 1549,

lob logical reads 0,

lob physical reads 0,

lob read-ahead reads 0.

Подход для SQL Server  2011
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE

USE TSQLDB;
GO

SET STATISTICS IO ON;
SET STATISTICS TIME ON;
GO

Declare @RowSkip As int
Declare @RowFetch As int

Set @RowSkip = 20000
Set @RowFetch = 50000

Select *
From dbo.tblSample
Order by (Select 1)
Offset @RowSkip Row
Fetch  Next @RowFetch Rows Only;
GO

SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;
GO

Время выполнения:

SQL Server Execution Times:

CPU time = 47 ms,  elapsed time = 626 ms.

Статистика ввода\вывода:

Scan count 1,

logical reads 530,

physical reads 0,

read-ahead reads 1549,

lob logical reads 0,

lob physical reads 0,

lob read-ahead reads 0.

Наиболее интересен результат по использованию процессорного времени (CPU Time) и время выполнения (Elapsed Time — время потребовавшееся запросу на выполнение). Сравнение замеров представлено ниже:





Sql Server VersionCPU TimeElapsed Time
2000110ms839 ms
2005/200878ms631 ms
201146ms626 ms

 

В таблице наглядно представлено, что новый SQL Server работает заметно быстрее по сравнению с предыдущими версиями. Естественно, что для вашей машины замеры времени могут отличаться, но производительность нового сервера будет всегда выше.

Альтернатива выражению TOP

Новые возможности Denali в некоторых ситуациях могут стать заменой выражению TOP.
Для примера возьмем ситуацию, когда необходимо получить первые 10 записей отсортированные по убыванию какого-либо параметра.

Подходы на предыдущих версиях

Select Top(10)
	 [Person ID]
	,[Person Name]
	,Age
	,DOB
	,Address
From dbo.tblSample
Order By Age Desc

Подход возможный в SQL Server Denali

Select
	 [Person ID]
	,[Person Name]
	,Age
	,DOB
	,Address
From dbo.tblSample
Order By Age Desc
Offset 10 Rows

Как заметили в комментариях это неверный код и вернет результат обратный Top(10).

Переводы из цикла:

MS SQL Server 2011: Автономные базы данных, новый объект Sequence, оператор Offset, обработка ошибок, конструкция With Result Set, новое в SSMS.

методы fetchall, fetchmany, fetchone, Binary, iterdump

Продолжим
изучение API для работы с SQLite на языке Python и пару слов о
способе извлечения данных из запросов. Об этом мы уже говорили на одном из
предыдущих занятий, когда рассматривали методы:


  • fetchall() – возвращает
    число записей в виде упорядоченного списка;

  • fetchmany(size) – возвращает
    число записей не более size;

  • fetchone() – возвращает
    первую запись.

Ссылку на это
занятие вы найдете в описании под этим видео (https://youtu.be/fYGfBpuFu0A). Я здесь лишь
напомню порядок применения этим функций. Для начала наполним БД cars записями:

import sqlite3 as sq
 
cars = [
    ('Audi', 52642),
    ('Mercedes', 57127),
    ('Skoda', 9000),
    ('Volvo', 29000),
    ('Bentley', 350000)
]
 
with sq.connect("cars.db") as con:
    cur = con.cursor()
 
    cur.executescript("""CREATE TABLE IF NOT EXISTS cars (
            car_id INTEGER PRIMARY KEY AUTOINCREMENT,
            model TEXT,
            price INTEGER)
    """)
 
    cur.executemany("INSERT INTO cars VALUES(NULL,?, ?)", cars)

И, затем,
выполним запрос на выборку записей:

cur.execute("SELECT model, price FROM cars")

Чтобы в
программе на Python получить доступ
к сформированной выборке, как раз и нужно воспользоваться функциями:

fetchall, fetchmany или fetchone

следующим
образом:

rows = cur.fetchall()
print(rows)

В консоли увидим
список из кортежей с данными записей в соответствии с указанными полями model и price:

[(‘Audi’,
52642), (‘Mercedes’, 57127), (‘Skoda’, 9000), (‘Volvo’, 29000), (‘Bentley’,
350000)]

По аналогии для
fetchone:

будет взята
только первая запись. И для fetchmany:

берем не более
четырех первых записей:

[(‘Audi’,
52642), (‘Mercedes’, 57127), (‘Skoda’, 9000), (‘Volvo’, 29000)]

Наконец, мы
говорили, что после формирования выборки сам экземпляр класса Cursor можно
использовать как итерируемый объект и выбирать записи в цикле:

for result in cur:
    print(result)

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

Далее, иногда
более предпочтительным вариантом выходных данных является не кортеж с данными,
а словарь, позволяющий обращаться к элементам по именам полей. Для этого после
установления соединения с БД следует прописать вот такую строчку:

Теперь, при
выполнении программы увидим, что переменная result в цикле
ссылается на объект Row, а не кортеж:

<sqlite3.Row
object at 0x00000185B226B8B0>

И через этот
объект доступ к данным осуществляется с помощью имен полей таблицы cars:

print(result['model'], result['price'])

Хранение изображений в БД

Часто в БД требуется
хранить небольшие изображения, например, аватары пользователей. Для этого
имеется специальный тип данных BLOB. Давайте создадим таблицу users с полем ava:

cur.executescript("""CREATE TABLE IF NOT EXISTS users (
    name TEXT,
    ava BLOB,
    score INTEGER)
""")

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

def readAva(n):
    try:
        with open(f"avas/{n}.png", "rb") as f:
            return f.read()
    except IOError as e:
        print(e)
        return False

Если изображение
было успешно прочитано, то функция возвратит набор двоичных данных, иначе
значение False. Затем, в
менеджере контекста БД вызовем ее и при успешном чтении данных записываем в
таблицу users:

img = readAva(1)
if img:
    binary = sq.Binary(img)
    cur.execute("INSERT INTO users VALUES ('Николай', ?, 1000)", (binary,))

Обратите
внимание, прежде чем бинарные данные передавать в поле BLOB их нужно
закодировать в бинарный объект модуля SQLite. Для этого и
вызывается метод Binary, которому передается последовательность
прочитанных байт изображения.

Запустим
программу и перейдем в приложение DB Browser. Откроем там
таблицу users. И при выборе
поля BLOB справа увидим
изображение, которое там хранится:

Давайте теперь
прочитаем изображение из этого поля. Выполним следующий запрос:

cur.execute("SELECT ava FROM users LIMIT 1")

и с помощью
метода fetchone обратимся к первой (и единственной) записи и возьмем данные из
поля ava:

img = cur.fetchone()['ava']

Чтобы нам знать,
что изображение было успешно прочитано, сохраним его в файл. Для этого запишем
вот такую функцию:

def writeAva(name, data):
    try:
        with open(name, "wb") as f:
            f.write(data)
    except IOError as e:
        print(e)
        return False
 
    return True

И вызовем ее:

У нас в рабочем
каталоге программы появился файл out.png и при его
просмотре видим, что это то самое изображение. Вот так производится запись и
чтение бинарных данных в SQLite.

Создание бэкапа БД

Класс Cursor содержит один
весьма полезный метод

iterdump()

возвращающий
итератор для SQL-запросов, на
основе которых можно воссоздать текущую БД. Если просто вывести в консоль
возвращаемых строк:

with sq.connect("cars.db") as con:
    cur = con.cursor()
 
    for sql in con.iterdump():
        print(sql)

То получим
список следующих SQL-команд:

BEGIN TRANSACTION;
CREATE TABLE cars (
            car_id INTEGER PRIMARY KEY AUTOINCREMENT,
            model TEXT,
            price INTEGER);
INSERT INTO "cars" VALUES(1,'Audi',0);
INSERT INTO "cars" VALUES(2,'Mercedes',57127);
INSERT INTO "cars" VALUES(3,'Skoda',9000);
INSERT INTO "cars" VALUES(4,'Volvo',29000);
INSERT INTO "cars" VALUES(5,'Bentley',350000);
DELETE FROM "sqlite_sequence";
INSERT INTO "sqlite_sequence" VALUES('cars',5);
CREATE TABLE users (
            name TEXT,
            ava BLOB,
            score INTEGER);
INSERT INTO "users" VALUES('Николай', …,1000);
COMMIT;

С помощью этих
запросов можно точно воссоздать таблицы БД, то есть, их можно рассматривать как
некий дамп БД.

Чтобы наша
программа выглядела более функциональной, сохраним все эти строчки в отдельном
файле:

    with open("sql_damp.sql", "w") as f:
        for sql in con.iterdump():
            f.write(sql)

После запуска в
рабочем каталоге программы появится файл sql_damp.sql с набором
соответствующих команд.

Теперь, чтобы
восстановить БД с помощью этого файла можно воспользоваться методом executescript,
о котором мы уже говорили:

    with open("sql_damp.sql", "r") as f:
        sql = f.read()
        cur.executescript(sql)

Перед
выполнением этой программы удалим файл cars.db и после запуска
снова увидим этот файл с прежним содержимым.

Создание БД в памяти

Интересной
особенностью модуля SQLite является возможность создания БД
непосредственно в памяти. Такая организация позволяет хранить временные данные
программы в формате таблиц и работать с ними через SQL-запросы. В ряде
случаев это бывает весьма удобно.

Для создания БД
в памяти устройства подключение записывается в виде:

data = [("car", "машина"), ("house", "дом"), ("tree", "дерево"), ("color", "цвет")]
 
con = sq.connect(':memory:')
with con:
    cur = con.cursor()
    cur.execute("""CREATE TABLE IF NOT EXISTS dict(
        eng TEXT, rus TEXT    
    )""")
 
    cur.executemany("INSERT INTO dict VALUES(?,?)", data)
 
    cur.execute("SELECT rus FROM dict WHERE eng LIKE 'c%'")
    print(cur.fetchall())

Мы здесь создали
подключение, указав специальный параметр «:memory:», что означает
«память» и, затем, в менеджере контекста создали таблицу dict с двумя полями,
заполнили ее значениями и сделали выборку всех английских слов, начинающихся с
первой буквы ‘c’.

Этот пример
показывает как можно использовать богатые возможности СУБД для хранения и
выборки данных в процессе работы приложения, не создавая на диске БД.

На этом мы
завершим цикл занятий по SQLite. Данного материала вам вполне
хватит для большинства приложений. Ну а по мере его использования неминуемо
узнаете многие другие нюансы работы данного модуля.

пропускает N строк перед началом возврата любых строк

Сводка : в этом руководстве вы узнаете, как использовать предложение SQL FETCH для ограничения количества строк, возвращаемых запросом.

Введение в предложение SQL FETCH

Чтобы ограничить количество строк, возвращаемых запросом, вы используете предложение LIMIT . Предложение LIMIT широко поддерживается многими системами баз данных, такими как MySQL, h3 и HSQLDB. Однако предложение LIMIT не является стандартным предложением SQL.

SQL: 2008 представил предложение OFFSET FETCH , которое имеет функцию, аналогичную предложению LIMIT . Предложение OFFSET FETCH позволяет пропустить N первых строк в наборе результатов перед началом возврата любых строк.

Ниже показан синтаксис предложения SQL FETCH :

 

OFFSET offset_rows {ROW | ROWS} ПОИСК {ПЕРВЫЙ | NEXT} [fetch_rows] {ROW | ROWS} ONLY

В этом синтаксисе:

  • ROW и ROWS , FIRST и NEXT являются синонимами, поэтому вы можете использовать их как взаимозаменяемые.
  • offset_rows — целое число, которое должно быть нулевым или положительным. Если offset_rows больше, чем количество строк в наборе результатов, никакие строки не будут возвращены.
  • fetch_rows также является целым числом, определяющим количество возвращаемых строк. Значение fetch_rows равно или больше единицы.

Поскольку строки хранятся в таблице в непредсказуемом порядке, вы всегда должны использовать предложение FETCH с предложением ORDER BY для получения согласованного вывода.

Многие системы баз данных поддерживают условие OFFSET FETCH , включая Oracle Database 12c +, PostgreSQL 10+ и Microsoft SQL Server 2012+. Однако каждая система базы данных реализует предложение OFFSET FETCH по-разному с некоторыми отклонениями.

Предложение OFFSET FETCH обычно используется в клиентских или веб-приложениях, требующих разбивки на страницы. Например, если на каждой странице десять строк, чтобы получить строки второй страницы, вы можете пропустить первые десять строк и вернуть следующие десять строк.

Примеры SQL FETCH

Мы будем использовать таблицу сотрудников в примере базы данных для демонстрации.

Следующий оператор возвращает первого сотрудника с самой высокой зарплатой:

 

SELECT employee_id, Имя, фамилия, оплата труда ОТ сотрудников СОРТИРОВАТЬ ПО зарплата DESC СМЕЩЕНИЕ 0 СТРОК ВЫБРАТЬ ТОЛЬКО СЛЕДУЮЩИЙ 1 РЯД;

В этом примере сначала предложение ORDER BY сортирует сотрудников по заработной плате от большего к меньшему.Предложение OFFSET пропускает нулевые строки, а предложение FETCH возвращает первую строку.

Следующий оператор сортирует сотрудников по зарплате, пропускает первые пять сотрудников с самой высокой зарплатой и выбирает следующие пять.

 

ВЫБРАТЬ employee_id, Имя, фамилия, оплата труда ОТ сотрудников СОРТИРОВАТЬ ПО зарплата DESC СМЕЩЕНИЕ 5 РЯДОВ ВЫБРАТЬ ТОЛЬКО СЛЕДУЮЩИЕ 5 РЯДОВ;

В этом руководстве вы узнали, как использовать предложение SQL FETCH для пропуска N строк в наборе результатов перед началом возврата любых строк.

  • Было ли это руководство полезным?
  • Да Нет

.

Ограничение количества возвращаемых строк

Сводка : в этом руководстве вы узнаете, как использовать предложения SQL Server OFFSET FETCH для ограничения количества строк, возвращаемых запросом.

Предложения OFFSET и FETCH являются вариантами предложения ORDER BY . Они позволяют ограничить количество строк, возвращаемых запросом.

Ниже показан синтаксис предложений OFFSET и FETCH :

 

ORDER BY column_list [ASC | DESC] OFFSET offset_row_count {ROW | ROWS} ПОИСК {ПЕРВЫЙ | ДАЛЕЕ} fetch_row_count {ROW | ТОЛЬКО ROWS}

В этом синтаксисе:

  • Предложение OFFSET указывает количество строк, которые нужно пропустить перед началом возврата строк из запроса. offset_row_count может быть константой, переменной или параметром, который больше или равен нулю.
  • Предложение FETCH определяет количество строк, возвращаемых после обработки предложения OFFSET . offset_row_count может быть константой, переменной или скаляром, который больше или равен единице.
  • Предложение OFFSET является обязательным, а предложение FETCH — необязательным. Кроме того, FIRST и NEXT являются синонимами соответственно, поэтому вы можете использовать их как взаимозаменяемые.Точно так же вы можете использовать FIRST и NEXT как взаимозаменяемые.

Следующее иллюстрирует предложения OFFSET и FETCH :

Обратите внимание, что вы должны использовать предложения OFFSET и FETCH с предложением ORDER BY . В противном случае вы получите ошибку.

Предложения OFFSET и FETCH предпочтительнее для реализации решения с разбивкой по страницам, чем предложение TOP .

Предложения OFFSET и FETCH доступны с SQL Server 2012 (11.x) и более поздних версий и базы данных SQL Azure.

SQL Server OFFSET и Примеры FETCH

Мы будем использовать таблицу products из образца базы данных для демонстрации.

Следующий запрос возвращает все продукты из таблицы products и сортирует продукты по их прейскурантным ценам и названиям:

 

SELECT наименование товара, список цен ОТ производство.продукты СОРТИРОВАТЬ ПО список цен, наименование товара;

Чтобы пропустить первые 10 продуктов и вернуть остальные, используйте предложение OFFSET , как показано в следующем утверждении:

 

SELECT наименование товара, список цен ОТ production.products СОРТИРОВАТЬ ПО список цен, наименование товара СМЕЩЕНИЕ 10 РЯДОВ;

Чтобы пропустить первые 10 продуктов и выбрать следующие 10 продуктов, используйте предложения OFFSET и FETCH следующим образом:

 

SELECT наименование товара, список цен ОТ производство.продукты СОРТИРОВАТЬ ПО список цен, наименование товара СМЕЩЕНИЕ 10 РЯДОВ ВЫБРАТЬ ТОЛЬКО СЛЕДУЮЩИЕ 10 РЯДОВ;

Чтобы попасть в топ-10 самых дорогих продуктов, вы используете предложения OFFSET и FETCH :

 

SELECT наименование товара, список цен ОТ production.products СОРТИРОВАТЬ ПО list_price DESC, наименование товара СМЕЩЕНИЕ 0 СТРОК ВЫБРАТЬ ТОЛЬКО ПЕРВЫЕ 10 РЯДОВ;

В этом примере предложение ORDER BY сортирует продукты по их прейскурантным ценам в порядке убывания.Затем предложение OFFSET пропускает нулевую строку, а предложение FETCH выбирает первые 10 продуктов из списка.

В этом руководстве вы узнали, как использовать предложения SQL Server OFFSET FETCH , которые ограничивают количество строк, возвращаемых запросом.

.

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

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