Desc limit: Оптимизируем LIMIT offset / Хабр

Содержание

Запрос SQL на выборку определённого числа записей

Вы здесь: Главная - MySQL - SQL - Запрос SQL на выборку определённого числа записей

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

Давайте сразу рассмотрим запрос SQL на выборку определённого числа записей:

SELECT * FROM users WHERE id > 5 LIMIT 10

Данным запросом мы получим 10 первых записей. Все остальные отпадут. Изменение от обычного SQL-запроса на выборку данных состоит только в параметре "LIMIT". Число, которое идёт за ним, сообщает, какое количество записей мы хотим получить, и в нашем случае - это 10.

Также существует возможность задавать после "LIMIT" два числа:

SELECT * FROM users WHERE id > 5 LIMIT 10, 20

Данный SQL-запрос вернёт записи, начиная с 10-го номера включительно в количестве 20-ти штук. То есть первое число означает, с какой записи надо формировать результат выборки, а второе число означает, какое количество записей всего должно быть.

Собственно, это всё, что необходимо для выборки определённого числа записей. Используется это очень часто, например, при выводе последних 10-ти зарегистрированных пользователях. Или при выводе 5-ти свежих статей (как на главной странице моего сайта), или в других аналогичных ситуациях.

  • Создано 18.01.2011 21:35:07
  • Михаил Русаков
Предыдущая статья Следующая статья

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov. ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:
    <a href="https://myrusakov.ru" target="_blank"><img src="https://myrusakov.ru/images/button.gif" alt="Как создать свой сайт" /></a>

    Она выглядит вот так:

  2. Текстовая ссылка:
    <a href="https://myrusakov.ru" target="_blank">Как создать свой сайт</a>

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):
    [URL="https://myrusakov. ru"]Как создать свой сайт[/URL]

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

Дата: 15.09.2019

Автор: Василий Лукьянчиков , vl (at) sqlinfo (dot) ru

Судя по сообщениям на форуме SQLinfo, выбор более одной строки из группы - часто встречающаяся задача (например, несколько популярных/новых товаров из каждой категории, последние новости для каждой рубрики, и т.д.), которая вызывает сложности при попытке решить её средствами SQL. В статье объясняется несколько способов как одним запросом получить N первых, последних или случайных строк из группы и дана оценка их эффективности с точки зрения производительности.

Разберем решения на примере таблицы сообщений, имеющей поля (post_id, user_id, date_added, post_text), в которой хранится id сообщения, id пользователя, дата добавления и текст поста. Предполагается, что комбинация (user_id, date_added) уникальна, т.е. пользователь не может разместить 2 сообщения в один момент времени.

Код создания и заполнения таблицы CREATE TABLE `posts` (
  `post_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `post_text` text NOT NULL,
  PRIMARY KEY (`post_id`),
  UNIQUE KEY `user_id` (`user_id`,`date_added`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `posts` VALUES (1,1,'2018-04-17 05:37:15','Есть таблица товаров. Каждый товар относится к какой-то категории. Как вывести по 3 товара из каждой категории?');
INSERT INTO `posts` VALUES (2,1,'2018-04-17 05:43:26','В идеале хочется получить последние N товаров из каждой категории одним запросом. Может есть какой-нибудь элегантный способ?');
INSERT INTO `posts` VALUES (3,2,'2018-04-17 11:13:22','Выборка по N последних товаров каждой категории. Просто не хочется делать запрос на каждую категорию.');
INSERT INTO `posts` VALUES (4,1,'2018-04-17 15:38:04','Как вывести по N строк из каждой группы? Например, последние новости для каждой рубрики или несколько популярных товаров из каждой категории');
INSERT INTO `posts` VALUES (5,1,'2018-04-17 15:52:18','Помогите написать запрос. Выбор по несколько строк из каждой группы в запросе');

INSERT INTO `posts` VALUES (6,4,'2018-04-18 12:17:05','MySQL не поддерживает LIMIT внутри IN подзапросов. Как написать запрос с лимитом строк внутри каждой группы?');
INSERT INTO `posts` VALUES (7,4,'2018-04-18 14:55:36','К сожалению, в MySQL нет windows function. Используйте user variables для их эмуляции.');
INSERT INTO `posts` VALUES (8,1,'2018-04-23 02:17:14','Помогите ускорить выборку случайных строк из группы.');
INSERT INTO `posts` VALUES (9,4,'2018-04-25 17:22:02','TOP в подзапросе выдает ошибку.');
INSERT INTO `posts` VALUES (10,4,'2018-04-26 22:28:45','Нужно выбрать из каждой группы по 2 последних элемента и 2 случайных.');

Пусть нам требуется выбрать 3 последних сообщения каждого пользователя. Некоторые из предложенных ниже вариантов после незначительных изменений могут быть использованы для выборки 3 случайных сообщений каждого пользователя (о чем будут даны соответствующие пояснения).

1. зависимый подзапрос

Для каждой строки таблицы считаем количество строк с тем же идентификатором пользователя (user_id) и большей датой добавления (date_added). Если количество таких строк меньше 3, значит рассматриваемая строка и есть нужная нам строка, т.е. входит в группу трёх последних сообщений пользователя.

select t1.* from posts t1
where (select count(*) from posts t2 where t1.user_id=t2.user_id and t2.date_added > t1.date_added) < 3;

Эффективность запроса ухудшается по мере роста числа сообщений у пользователя. Нельзя ограничится рассмотрением только нескольких записей каждого пользователя, необходимо проверить все сообщения и для каждого из них подсчитать точное кол-во более поздних. Кроме того метод неприменим для выборки нескольких случайных строк из группы.

2. join + group by

Та же идея, что и в предыдущем случае, только реализована через самообъединение таблицы и группировку. Каждой строке сопоставляется набор строк с тем же user_id и большей или равной date_added, после группировки мы получаем для каждой строки (количество сообщений того же пользователя с большей датой добавления) + 1. Иными словами, если мы пронумеруем сообщения пользователя по убыванию date_added, то полученное число будет порядковым номером строки в этой нумерации.

select t1.* from
posts t1 join posts t2 on t1.user_id=t2.user_id and t2.date_added >= t1.date_added
group by t1.post_id
having count(*) <=3;

Этот способ часто рекомендуют в интернете в качестве решения задачи (встречаются вариации с left join). Однако его производительность не самая оптимальная в сравнении с другими методами, рассмотренными в этой статье. Вероятно, причина популярности этого решения в том, что join многим интуитивно представляется более простым решением.

Обратите внимание: в режиме ONLY_FULL_GROUP_BY придется усложнять запрос: сначала выбрать нужные post_id, затем по ним дополнительным join извлечь остальные поля (подробнее см статью Группировка в MySQL). Простое перечисление всех полей в части group by в разы увеличивает время выполнения запроса.

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

Вместо исходной таблицы в запросе будет использоваться результат select posts.*, rand() new_col from posts, и сравнение не по полю date_added, а по new_col. Будем считать, что варианты 1 и 2 не применимы для поиска случайных строк в группах, потому что:

  • в старых версиях они действительно не применимы 🙂
  • в новых их производительность будет существенно хуже по сравнению с иными доступными вариантами решений (см способы 4 и 6)

3. group_concat()

Для каждого пользователя с помощью group_concat() составляется список идентификаторов его сообщений, отсортированный по убыванию даты. Используя substring_index(), вырезаем первые 3 значения post_id, и по ним извлекается вся строка.

select t1.* from posts t1 join
(select user_id, substring_index(group_concat(post_id order by date_added desc), ',', 3) x from posts t2 group by user_id) t
on t.user_id = t1.user_id and find_in_set(t1.post_id,x);

К сожалению, MySQL не умеет решать уравнения, поэтому для поиска по условию с find_in_set будет просканирована вся таблица сообщений.

Есть обходной путь: используя строковые функции и union all, вырезать id сообщений из списка и объединить их в один столбец. Тогда оптимизатор сможет использовать их для поиска нужных строк в таблице сообщений, а не наоборот.

with cte as (
select substring_index(group_concat(post_id order by date_added desc), ',', 3) x from posts group by user_id
)
select posts.* from (
select substring_index(x,',',1) post_id from cte
union all
select substring_index(substring_index(x,',',2),',',-1) from cte
union all
select substring_index(x,',',-1) from cte) t
join posts on t.post_id = posts.post_id;

Будет ли такой трюк эффективным зависит от:

  • сколько строк из группы нужно выбрать
  • есть ли возможность использовать with (доступны с MariaDB 10.2 / MySQL 8). Если в явном виде дублировать from-подзапрос, то каждый из них будет материализован в отдельную временную таблицу.

Этот способ можно применять для выборки 3 случайных сообщений каждого пользователя.

Для этого достаточно указать иной вид сортировки внутри group_concat: order by rand() вместо order by date_added desc.

4. оконные функции

Начиная с MariaDB 10.2 / MySQL 8 добавлена поддержка оконных функций. С помощью row_number() можно для каждого пользователя сделать отдельную нумерацию сообщений в порядке убывания даты. После чего выбрать те записи, у которых № меньше или равен 3.

select post_id, user_id, date_added, post_text from
(select posts.*,
row_number() over (partition by user_id order by date_added desc) i
from posts) t where i <= 3;

Производительность - двойное сканирование таблицы: сначала для нумерации (нет возможности ограничиться нумерацией только нескольких строк из группы), потом отбросить не удовлетворяющие условию where i <= 3.

Для случайных сообщений пользователя достаточно заменить сортировку по убыванию даты order by date_added desc на случайную - order by rand().

5. пользовательские переменные

Та же идея, что и в предыдущем варианте, только реализована с помощью пользовательских переменных (user variables).

Актуально для версий, в которых нет оконных функций.

select post_id, user_id, date_added, post_text from
(select posts.*, if(@gr=user_id, @i:[email protected]+1, @i:=1 + least(@gr:=user_id,0)) x
from posts, (select @i:=0, @gr:=0) t order by user_id, date_added desc) t1 where x <=3;

Как и в примере с row_number(), мы нумеруем сообщения каждого пользователя в порядке убывания даты добавления (только делаем это с помощью пользовательских переменных), затем оставляем только те строки, у которых № меньше или равен 3.

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

select post_id, user_id, date_added, post_text from
(select t2.*, if(@gr=user_id, @i:[email protected]+1, @i:=1 + least(@gr:=user_id,0)) x
from (select posts.*, rand() q, @z:=1 from posts) t2, (select @i:=0, @gr:=0) t order by user_id, q) t1 where x <=3

Обратите внимание на добавление ещё одной переменной @z:=1, которая более нигде не применяется. С некоторых пор оптимизатор научился упрощать тривиальные с его точки зрения from-подзапросы, перенося условия из них во внешний запрос. Однако, если в подзапросе используются переменные, то пока оптимизатор материализует такие подзапросы.

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

6. подзапросы lateral

В MySQL 8.0.14 добавлена поддержка зависимых подзапросов в части FROM, с помощью которых наша задача решается оптимальным образом. Сначала формируется список идентификаторов пользователей (производная таблица t1) и для каждого из выбираются нужные строки (коррелированный from-подзапрос t2).

select t2.* from (select user_id from posts group by user_id) as t1,
lateral (select * from posts where t1. user_id=posts.user_id order by date_added desc limit 3) as t2;

К удивлению, при выборе строк в подзапросе t2 сервер читает все строки группы и делает файловую сортировку вместо нахождения 3 нужных строк по уникальному индексу (user_id, date_added). Возможно в будущих версиях это поведение будет исправлено.

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

.. order by user_id desc, date_added desc limit 3

Спасибо за совет Гильяму Бишоту.

Для выборки случайных строк из группы достаточно в lateral подзапросе заменить сортировку на случайную - order by rand().

Заключение

Сводная таблица, показывающая среднее время выполнения изложенных выше способов для нахождения трёх последних и трёх случайных сообщений каждого пользователя на тестовых данных в 16000 строк, равномерно распределенных среди count(distinct user_id) = 20.

время, с
3 последних 3 случайных
1. зависимый подзапрос 10.8 -
2. join + group by 11 -
3. group_concat() 0.06 0.03
3. модифицированный вариант + WITH 0.03 0.016
3. модифицированный вариант без WITH 0.08 -
4. row_number() 0.15 0.17
5. пользовательские переменные 0.13 0.14
6. LATERAL 0.005 0.03

Если ваша СУБД поддерживает подзапросы lateral, то используйте их. Вообще, каждый раз, когда есть необходимость "для каждого значения выбрать ..." - возможно вы сможете эффективно решить задачу, используя LATERAL производные таблицы. Подробнее об этой функциональности можно прочитать в статье В MySQL 8.0.14 добавлена поддержка производных таблиц типа LATERAL.

Неожиданно высокую эффективность показал третий способ, особенно для выборки случайных строк из группы. Неожиданно, потому что как правило рекомендуют использовать второй и четвертый (для MySQL до недавнего времени его реализацию через переменные, т.е. пятый) способы.

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

P.S.При выборе подходящего варианта проводите тестирование в своем окружении.
Если после прочтения статьи ваш вопрос остался нерешенным, задавайте его на форуме SQLinfo.

Дата публикации: 15. 09.2019

© Все права на данную статью принадлежат порталу SQLInfo.ru. Перепечатка в интернет-изданиях разрешается только с указанием автора и прямой ссылки на оригинальную статью. Перепечатка в бумажных изданиях допускается только с разрешения редакции.

Как получить 10 лучших значений в postgresql?

Вопрос:

У меня простой вопрос:

У меня есть база данных postgresql: Scores(score integer).

Как бы я получил самые высокие 10 баллов быстрее?

ОБНОВИТЬ:

Я буду делать этот запрос несколько раз и стремлюсь к самому быстрому решению.

Ответ №1

Для этого вы можете использовать лимит

select *
from scores
order by score desc
limit 10

Если важна производительность (когда это не так ;-), ищите индекс на счет.


Начиная с версии 8.4, вы также можете использовать стандарт (SQL: 2008) fetch first

select *
from scores
order by score desc
fetch first 10 rows only

Как отметил @Raphvanns, это даст вам буквально first 10 rows. Чтобы удалить повторяющиеся значения, необходимо выбрать distinct строк, например.

select distinct *
from scores
order by score desc
fetch first 10 rows only

SQL Fiddle

Ответ №2

Кажется, что вы ищете ORDER BY в DESC окончательном порядке с LIMIT:

SELECT
*
FROM
scores
ORDER BY score DESC
LIMIT 10

Конечно, SELECT * может серьезно повлиять на производительность, поэтому используйте его с осторожностью.

Ответ №3

Обратите внимание, что если есть связи в первых 10 значениях, вы получите только первые 10 строк, а не 10 лучших значений с предоставленными ответами. Пример: если верхние 5 значений 10, 11, 12, 13, 14, 15, но ваши данные содержат 10, 10, 11, 12, 13, 14, 15, вы получите только 10, 10, 11, 12, 13, 14 в качестве верхней 5 с LIMIT

Вот решение, которое будет возвращать более 10 строк, если есть связи, но вы получите все строки, где some_value_column технически находятся в топ-10.

select
*
from
(select
*,
rank() (order by some_value_column desc) as my_rank
from
mytable) subquery
where my_rank <= 10

Ответ №4

(SELECT <some columns>
FROM mytable
<maybe some joins here>
WHERE <various conditions>
ORDER BY date DESC
LIMIT 10)

UNION ALL

(SELECT <some columns>
FROM mytable
<maybe some joins here>
WHERE <various conditions>
ORDER BY date ASC
LIMIT 10)

PostgreSQL : Документация: 9.6: CREATE INDEX : Компания Postgres Professional

Описание

CREATE INDEX создаёт индексы по указанному столбцу(ам) заданного отношения, которым может быть таблица или материализованное представление. Индексы применяются в первую очередь для оптимизации производительности базы данных (хотя при неправильном использовании возможен и противоположный эффект).

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

Поле индекса может быть выражением, вычисляемым из значений одного или нескольких столбцов в строке таблицы. Это может быть полезно для получения быстрого доступа к данным по некоторому преобразованию исходных значений. Например, индекс, построенный по выражению upper(col), позволит использовать поиск по индексу в предложении WHERE upper(col) = 'JIM'.

PostgreSQL предоставляет следующие методы индексов: B-дерево, хеш, GiST, SP-GiST, GIN и BRIN. Пользователи могут определить и собственные методы индексов, но это довольно сложная задача.

Если в команде присутствует предложение WHERE, она создаёт частичный индекс. Такой индекс содержит записи только для части таблицы, обычно более полезной для индексации, чем остальная таблица. Например, если таблица содержит информацию об оплаченных и неоплаченных счетах, при этом последних сравнительно немного, но именно эта часть таблицы наиболее востребована, то увеличить быстродействие можно, создав индекс только по этой части. Ещё одно возможное применение WHERE — добавив UNIQUE, обеспечить уникальность в подмножестве таблицы. Подробнее это рассматривается в Разделе 11.8.

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

Все функции и операторы, используемые в определении индекса, должны быть «постоянными», то есть, их результаты должны зависеть только от аргументов, но не от внешних факторов (например, содержимого другой таблицы или текущего времени). Это ограничение обеспечивает определённость поведения индекса. Чтобы использовать в выражении индекса или в предложении WHERE собственную функцию, не забудьте пометить её при создании как постоянную (IMMUTABLE).

Производительность max () против ORDER BY DESC + LIMIT 1

Я искал несколько медленных SQL-запросов сегодня и не совсем понимаю разницу в производительности ниже:

При попытке извлечь max (timestamp) из таблицы данных на основе некоторого условия использование MAX() выполняется медленнее, чем ORDER BY timestamp LIMIT 1 если соответствующая строка существует, но значительно быстрее, если совпадающая строка не найдена.

SELECT timestamp
FROM data JOIN sensors ON ( sensors.id = data.sensor_id )
WHERE sensor.station_id = 4
ORDER BY timestamp DESC
LIMIT 1;
(0 rows)  
Time: 1314.544 ms

SELECT timestamp
FROM data JOIN sensors ON ( sensors.id = data.sensor_id )
WHERE sensor.station_id = 5
ORDER BY timestamp DESC
LIMIT 1;
(1 row)  
Time: 10.890 ms

SELECT MAX(timestamp)
FROM data JOIN sensors ON ( sensors.id = data.sensor_id )
WHERE sensor.station_id = 4;
(0 rows)
Time: 0.869 ms

SELECT MAX(timestamp)
FROM data JOIN sensors ON ( sensors.id = data.sensor_id )
WHERE sensor.station_id = 5;
(1 row)
Time: 84.087 ms 

Есть индексы на (timestamp) и (sensor_id, timestamp) , и я заметил, что Postgres использует очень разные планы и индексы запросов для обоих случаев:

QUERY PLAN (ORDER BY)                                              
--------------------------------------------------------------------------------------------------------
Limit  (cost=0. 43..9.47 rows=1 width=8)
    ->  Nested Loop  (cost=0.43..396254.63 rows=43823 width=8)
          Join Filter: (data.sensor_id = sensors.id)
          ->  Index Scan using timestamp_ind on data  (cost=0.43..254918.66 rows=4710976 width=12)
          ->  Materialize  (cost=0.00..6.70 rows=2 width=4)
              ->  Seq Scan on sensors  (cost=0.00..6.69 rows=2 width=4)
                  Filter: (station_id = 4)
(7 rows)

QUERY PLAN (MAX)                                               
----------------------------------------------------------------------------------------------------------
Aggregate  (cost=3680.59..3680.60 rows=1 width=8)
    ->  Nested Loop  (cost=0.43..3571.03 rows=43823 width=8)
        ->  Seq Scan on sensors  (cost=0.00..6.69 rows=2 width=4)
              Filter: (station_id = 4)
        ->  Index Only Scan using sensor_ind_timestamp on data  (cost=0.43..1389.59 rows=39258 width=12)
              Index Cond: (sensor_id = sensors.id)
(6 rows)

Итак, мои два вопроса:

  1. Откуда возникает эта разница в производительности? Я видел принятый ответ здесь MIN/MAX vs. ORDER BY и LIMIT , но это не совсем похоже на применение здесь. Любые хорошие ресурсы будут оценены.
  2. Есть ли более эффективные способы повышения производительности во всех случаях (совпадение строк с несоответствующей строкой), чем добавление проверки EXISTS ?

EDIT to address the questions in the comments below. I kept the initial query plans above for future reference:

Определения таблиц:

                                  Table "public.sensors"
        Column        |          Type          |                            Modifiers                            
----------------------+------------------------+-----------------------------------------------------------------
id                    | integer                | not null default nextval('sensors_id_seq'::regclass)
station_id            | integer                | not null
....

Indexes:
    "sensor_primary" PRIMARY KEY, btree (id)
    "ind_station_id" btree (station_id, id)
    "ind_station" btree (station_id)

                                  Table "public. data"
  Column   |           Type           |                            Modifiers                             
-----------+--------------------------+------------------------------------------------------------------
 id        | integer                  | not null default nextval('data_id_seq'::regclass)
 timestamp | timestamp with time zone | not null
 sensor_id | integer                  | not null
 avg       | integer                  |

Indexes:
    "timestamp_ind" btree ("timestamp" DESC)
    "sensor_ind" btree (sensor_id)
    "sensor_ind_timestamp" btree (sensor_id, "timestamp")
    "sensor_ind_timestamp_desc" btree (sensor_id, "timestamp" DESC)

Note that I added ind_station_id on sensors just now after @Erwin's suggestion below. Timings haven't really changed drastically, still >1200ms in the ORDER BY DESC + LIMIT 1 case and ~0.9ms in the MAX case.

Планы запросов:

QUERY PLAN (ORDER BY)
----------------------------------------------------------------------------------------------------------
Limit  (cost=0. 58..9.62 rows=1 width=8) (actual time=2161.054..2161.054 rows=0 loops=1)
  Buffers: shared hit=3418066 read=47326
  ->  Nested Loop  (cost=0.58..396382.45 rows=43823 width=8) (actual time=2161.053..2161.053 rows=0 loops=1)
        Join Filter: (data.sensor_id = sensors.id)
        Buffers: shared hit=3418066 read=47326
        ->  Index Scan using timestamp_ind on data  (cost=0.43..255048.99 rows=4710976 width=12) (actual time=0.047..1410.715 rows=4710976 loops=1)
              Buffers: shared hit=3418065 read=47326
        ->  Materialize  (cost=0.14..4.19 rows=2 width=4) (actual time=0.000..0.000 rows=0 loops=4710976)
              Buffers: shared hit=1
              ->  Index Only Scan using ind_station_id on sensors  (cost=0.14..4.18 rows=2 width=4) (actual time=0.004..0.004 rows=0 loops=1)
                    Index Cond: (station_id = 4)
                    Heap Fetches: 0
                    Buffers: shared hit=1
Planning time: 0.478 ms
Execution time: 2161.090 ms
(15 rows)

QUERY (MAX)
----------------------------------------------------------------------------------------------------------
Aggregate  (cost=3678. 08..3678.09 rows=1 width=8) (actual time=0.009..0.009 rows=1 loops=1)
   Buffers: shared hit=1
   ->  Nested Loop  (cost=0.58..3568.52 rows=43823 width=8) (actual time=0.006..0.006 rows=0 loops=1)
         Buffers: shared hit=1
         ->  Index Only Scan using ind_station_id on sensors  (cost=0.14..4.18 rows=2 width=4) (actual time=0.005..0.005 rows=0 loops=1)
               Index Cond: (station_id = 4)
               Heap Fetches: 0
               Buffers: shared hit=1
         ->  Index Only Scan using sensor_ind_timestamp on data  (cost=0.43..1389.59 rows=39258 width=12) (never executed)
               Index Cond: (sensor_id = sensors.id)
               Heap Fetches: 0
 Planning time: 0.435 ms
 Execution time: 0.048 ms
 (13 rows)

Так, как и в более ранних объяснениях, ORDER BY выполняет Scan, используя timestamp_in для данных , что не выполняется в случае MAX .

Postgres version: Postgres from the Ubuntu repos: PostgreSQL 9. 4.5 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu 5.2.1-21ubuntu2) 5.2.1 20151003, 64-bit

Обратите внимание, что существуют ограничения NOT NULL , поэтому ORDER BY не нужно сортировать пустые строки.

Note also that I'm largely interested in where the difference comes from. While not ideal, I can retrieve data relatively quickly using EXISTS ( and then SELECT (~11ms).

Тесты Базы данных SQL с ответами

Тесты на знание SQL с ответами

Правильный вариант ответа отмечен знаком +

1. Для создания новой таблицы в существующей базе данных используют команду:

- NEW TABLE

+ CREATE TABLE

- MAKE TABLE

2. Имеются элементы запроса: 1. SELECT employees.name, departments.name; 2. ON employees.department_id=departments.id; 3. FROM employees; 4. LEFT JOIN departments. В каком порядке их нужно расположить, чтобы выполнить поиск имен всех работников со всех отделов?

- 1, 4, 2, 3

- 1, 2, 4, 3

+ 1, 3, 4, 2

3. Как расшифровывается SQL?

+ structured query language

- strict question line

- strong question language

4. Запрос для выборки всех значений из таблицы «Persons» имеет вид:

- SELECT ALL Persons

+ SELECT * FROM Persons

- SELECT .[Persons]

5. Какое выражение используется для возврата только разных значений?

+ SELECT DISCINCT

- SELECT DIFFERENT

- SELECT UNIQUE

6. Для подсчета количества записей в таблице «Persons» используется команда:

- COUNT ROW IN Persons

+ SELECT COUNT(*) FROM Persons

- SELECT ROWS FROM Persons

7. Наиболее распространенным является тип объединения:

+ INNER JOIN

- FULL JOIN

- LEFT JOIN

8. Что возвращает запрос SELECT * FROM Students?

+ Все записи из таблицы «Students»

- Рассчитанное суммарное количество записей в таблице «Students»

- Внутреннюю структуру таблицы «Students»

9. Запрос «SELECT name ___ Employees WHERE age ___ 35 AND 50» возвращает имена работников, возраст которых от 35 до 50 лет. Заполните пропущенные места в запросе.

- INTO, IN

- FROM, IN

+ FROM, BETWEEN

тест 10. Какая агрегатная функция используется для расчета суммы?

+ SUM

- AVG

- COUNT

11. Запрос для выборки первых 14 записей из таблицы «Users» имеет вид:

+ SELECT * FROM Users LIMIT 14

- SELECT * LIMIT 14 FROM Users

- SELECT * FROM USERS

12. Выберите верное утверждение:

- SQL чувствителен к регистру при написании запросов

- SQL чувствителен к регистру в названиях таблиц при написании запросов

- SQL нечувствителен к регистру

13. Заполните пробелы в запросе «SELECT ___, Сountry FROM ___ », который возвращает имена заказчиков и страны, где они находятся, из таблицы «Customers».

- *, Customers

- NULL, Customers

+ Name, Customers

14. Запрос, возвращающий все значения из таблицы «Countries», за исключением страны с ID=8, имеет вид:

- SELECT * FROM Countries EXP ID=8

+ SELECT * FROM Countries WHERE ID !=8

- SELECT ALL FROM Countries LIMIT 8

15. Напишите запрос для выборки данных из таблицы «Customers», где условием является проживание заказчика в городе Москва

+ SELECT * FROM Customers WHERE City=”Moscow”

- SELECT City=”Moscow” FROM Customers

- SELECT Customers WHERE City=”Moscow”

16. Напишите запрос, возвращающий имена, фамилии и даты рождения сотрудников (таблица «Employees»). Условие – в фамилии содержится сочетание «se».

- SELECT FirstName, LastName, BirthDate from Employees WHERE LastName=“se”

- SELECT * from Employees WHERE LastName like “_se_”

+ SELECT FirstName, LastName, BirthDate from Employees WHERE LastName like “%se%”

17. Какая функция позволяет преобразовать все буквы в выбранном столбце в верхний регистр?

- TOP

+ UPPER

- UP

18. Напишите запрос, позволяющий переименовать столбец LastName в Surname в таблице «Employees».

- RENAME LastName into Surname FROM Employees

+ ALTER TABLE Employees CHANGE LastName Surname varchar(50)

- ALTER TABLE Surname(LastName) FROM Employees

19. Для создания новой виртуальной таблицы, которая базируется на результатах сделанного ранее SQL запроса, используется команда:

- CREATE VIRTUAL TABLE

+ CREATE VIEW

- ALTER VIEW

тест-20. В таблице «Emlpoyees» содержатся данные об именах, фамилиях и зарплате сотрудников. Напишите запрос, который изменит значение зарплаты с 2000 на 2500 для сотрудника с ID=7.

- SET Salary=2500 FROM Salary=2000 FOR ID=7 FROM Employees

- ALTER TABLE Employees Salary=2500 FOR ID=7

+ UPDATE Employees SET Salary=2500 WHERE ID=7

21. К какому результату приведет выполнение запроса DROP DATABASE Users?

+ Полное удаление базы данных «Users»

- Блокировка на внесение изменений в базу данных «Users»

- Удаление таблицы «Users» из текущей базы данных

22. В таблице «Animals» базы данных зоопарка содержится информация обо всех обитающих там животных, в том числе о лисах: red fox, grey fox, little fox. Напишите запрос, возвращающий информацию о возрасте лис.

- SELECT %fox age FROM Animals

+ SELECT age FROM Animals WHERE Animal LIKE «%fox»

- SELECT age FROM %Fox.Animals

23. Что возвращает запрос SELECT FirstName, LastName, Salary FROM Employees Where Salary<(Select AVG(Salary) FROM Employees) ORDER BY Salary DESC?

- Имена, фамилии и зарплаты сотрудников, значения которых соответствуют среднему значению среди всех сотрудников

- Имена, фамилии сотрудников и их среднюю зарплату за весь период работы, с выполнением сортировки по убыванию

+ Имена, фамилии и зарплаты сотрудников, для которых справедливо условие, что их зарплата ниже средней, с выполнением сортировки зарплаты по убыванию

24. Напишите запрос, возвращающий значения из колонки «FirstName» таблицы «Users».

+ SELECT FirstName FROM Users

- SELECT FirstName.Users

- SELECT * FROM Users.FirstName

25. Напишите запрос, возвращающий информацию о заказчиках, проживающих в одном из городов: Москва, Тбилиси, Львов.

- SELECT Moscow, Tbilisi, Lvov FROM Customers

+ SELECT * FROM Customers WHERE City IN (‘Moscow’, ‘Tbilisi’, ‘Lvov’)

- SELECT City IN (‘Moscow’, ‘Tbilisi’, ‘Lvov’) FROM Customers

26. Какая команда используется для объединения результатов запроса без удаления дубликатов?

UNION

+ UNION ALL

- FULL JOIN

27. Оператор REVOKE предназначен для:

- Предоставления пользователю или группе пользователей прав на осуществление определенных операций;

- Задавания пользователю или группе пользователей запрета, который является приоритетным по сравнению с разрешением;

+ Отзыва у пользователя или группы пользователей выданных ранее разрешений

28. Для чего в SQL используются aliases?

+ Для назначения имени источнику данных в запросе при использовании выражения в качестве источника данных или для упрощения структуры запросов

- Для переименования полей

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

29. Напишите запрос, который будет возвращать значения городов из таблицы «Countries».

- SELECT * FROM Countries WHERE ID=”City”

+ SELECT City FROM Countries

- SELECT City.Countries

тест_30. Имеются элементы запроса: 1. ORDER BY Name; 2. WHERE Age<19; 3. FROM Students; 4. SELECT FirstName, LastName. В каком порядке их нужно расположить, чтобы выполнить поиск имен и фамилий студентов в возрасте до 19 лет с сортировкой по имени?

- 1, 4, 2, 3

- 4, 2, 3, 1

+ 4, 3, 2, 1

31. Для чего в SQL используется оператор PRIVILEGUE?

- Для наделения суперпользователя правами администратора

- Для выбора пользователей с последующим наделением их набором определенных прав

+ Такого оператора не существует

32. Напишите запрос, который будет возвращать текущую дату.

+ SELECT GetDate()

- SELECT TodayDate()

- SELECT Date(Today)

33. Какой оператор используется для выборки значений в пределах заданного диапазона?

- WITHIN

- IN

+ BETWEEN

MySQL LIMIT

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

Введение в MySQL LIMIT Предложение

Предложение LIMIT используется в операторе SELECT для ограничения количества возвращаемых строк. Предложение LIMIT принимает один или два аргумента. Значения обоих аргументов должны быть нулевыми или положительными целыми числами.

Ниже показан синтаксис предложения LIMIT с двумя аргументами:

 

SELECT select_list ИЗ table_name LIMIT [смещение,] row_count;

Язык кода: SQL (язык структурированных запросов) (sql)

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

  • Смещение указывает смещение первой возвращаемой строки. Смещение первой строки равно 0, а не 1.
  • row_count определяет максимальное количество возвращаемых строк.

На следующем рисунке показано предложение LIMIT :

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

Следовательно, эти два предложения эквивалентны:

 

LIMIT row_count;

Язык кода: SQL (язык структурированных запросов) (sql)

и

 

LIMIT 0, row_count;

В дополнение к приведенному выше синтаксису MySQL предоставляет следующее альтернативное предложение LIMIT для совместимости с PostgreSQL.

 

LIMIT row_count OFFSET offset

Язык кода: SQL (язык структурированных запросов) (sql)

LIMIT и Предложения ORDER BY

Оператор SELECT без предложения ORDER BY возвращает строки в неопределенном порядке. Это означает, что строки могут располагаться в любом порядке. Когда вы примените предложение LIMIT к этому неупорядоченному набору результатов, вы не будете знать, какие строки вернет запрос.

Например, вы можете захотеть получить строки с пятой по десятую, но с пятой по десятую в каком порядке? Порядок строк неизвестен, если вы не укажете условие ORDER BY .

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

 

ВЫБРАТЬ select_list FROM table_name ORDER BY order_expression LIMIT смещение, row_count;

Язык кода: SQL (язык структурированных запросов) (sql)

На следующем рисунке показан порядок оценки предложения LIMIT в операторе SELECT :

MySQL LIMIT примеров

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

1) Использование MySQL LIMIT для получения самых высоких или самых низких строк

Этот оператор использует предложение LIMIT для получения пяти лучших клиентов с наивысшим кредитным рейтингом:

 

SELECT номер клиента, Имя Клиента, кредитный лимит ИЗ клиенты ЗАКАЗАТЬ ПО кредитному лимиту УДАЛЕНИЕ LIMIT 5;

Язык кода: SQL (язык структурированных запросов) (sql)

Попробовать

В этом примере:

  • Во-первых, предложение ORDER BY сортирует клиентов по кредитам в порядке убывания.
  • Затем предложение LIMIT возвращает первые 5 строк.

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

 

SELECT номер клиента, Имя Клиента, кредитный лимит ИЗ клиенты ЗАКАЗАТЬ ПО кредитному лимиту LIMIT 5;

Язык кода: SQL (язык структурированных запросов) (sql)

Попробовать

В этом примере:

  • Во-первых, предложение ORDER BY сортирует клиентов по кредитам в порядке убывания.
  • Затем предложение LIMIT возвращает первые 5 строк.

Поскольку более 5 клиентов имеют нулевые кредиты, результат вышеприведенного запроса может привести к противоречивому результату.

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

 

SELECT номер клиента, Имя Клиента, кредитный лимит ИЗ клиенты СОРТИРОВАТЬ ПО кредитный лимит, номер клиента LIMIT 5;

Язык кода: SQL (язык структурированных запросов) (sql)

Попробовать

2) Использование MySQL LIMIT для разбивки на страницы

Когда вы отображаете данные в приложениях, вы часто хотите разделить строки на страницы, где каждая страница содержит определенное количество строк, например 5, 10 или 20.

Чтобы рассчитать количество страниц, вы получаете общее количество строк, разделенное на количество строк на странице. Для получения строк определенной страницы вы можете использовать предложение LIMIT .

В этом запросе используется агрегатная функция COUNT (*) для получения итоговых строк из таблицы customers :

 

SELECT COUNT (*) FROM customers;

Язык кода: SQL (язык структурированных запросов) (sql)
 

+ ---------- + | СЧЁТ (*) | + ---------- + | 122 | + ---------- + 1 ряд в комплекте (0.00 сек)

Язык кода: JavaScript (javascript)

Предположим, что каждая страница имеет 10 строк, для отображения 122 клиентов у вас есть 13 страниц. Последняя 13-я страница содержит только две строки.

Этот запрос использует предложение LIMIT для получения строк страницы 1, которая содержит первые 10 клиентов, отсортированных по имени клиента:

 

SELECT номер клиента, Имя Клиента ИЗ клиенты ЗАКАЗАТЬ ПО customerName LIMIT 10;

Язык кода: SQL (язык структурированных запросов) (sql)

Попробовать

В этом запросе используется предложение LIMIT для получения строк второй страницы, которые включают строку 11-20:

 

ВЫБРАТЬ номер клиента, Имя Клиента ИЗ клиенты ЗАКАЗАТЬ ПО customerName ПРЕДЕЛ 10, 10;

Язык кода: SQL (язык структурированных запросов) (sql)

Попробовать

В этом примере предложение LIMIT 10, 10 возвращает 10 строк для строки 11-20.

3) Использование MySQL LIMIT для получения n th наивысшего или наименьшего значения

Чтобы получить n-е наибольшее или наименьшее значение, вы используете следующее предложение LIMIT :

 

SELECT select_list FROM table_name ЗАКАЗАТЬ ПО sort_expression ПРЕДЕЛ n-1, 1;

Язык кода: SQL (язык структурированных запросов) (sql)

Предложение LIMIT n-1, 1 возвращает строку 1 , начиная со строки n .

Например, следующий код находит клиента, у которого второй по величине кредит:

 

SELECT Имя Клиента, кредитный лимит ИЗ клиенты СОРТИРОВАТЬ ПО creditLimit DESC LIMIT 1,1;

Язык кода: SQL (язык структурированных запросов) (sql)

Попробовать

Давайте еще раз проверим результат. Этот запрос возвращает всех клиентов, отсортированных по кредитам от большего к меньшему:

 

SELECT Имя Клиента, кредитный лимит ИЗ клиенты СОРТИРОВАТЬ ПО creditLimit DESC;

Язык кода: SQL (язык структурированных запросов) (sql)

Попробовать

Как ясно видно из выходных данных, результат оказался правильным, как и ожидалось.

Обратите внимание, что этот метод работает, когда нет двух клиентов с одинаковыми кредитными лимитами. Для получения более точного результата следует использовать оконную функцию DENSE_RANK () .

В этом руководстве вы узнали, как использовать предложение MySQL LIMIT для ограничения количества строк, возвращаемых оператором SELECT .

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

SQL: SELECT LIMIT Statement


В этом руководстве по SQL объясняется, как использовать оператор SELECT LIMIT в SQL с синтаксисом и примерами.

Описание

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

СОВЕТ: SELECT LIMIT поддерживается не во всех базах данных SQL.

Для таких баз данных, как SQL Server или MSAccess, используйте оператор SELECT TOP, чтобы ограничить результаты. Оператор SELECT TOP является проприетарным эквивалентом оператора SELECT LIMIT от Microsoft.

Синтаксис

Синтаксис оператора SELECT LIMIT в SQL:

 Выражения SELECT
ИЗ столов
[ГДЕ условия]
[ORDER BY выражение [ASC | DESC]]
LIMIT number_rows [OFFSET offset_value]; 

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

выражений
Столбцы или вычисления, которые вы хотите получить.
столов
Таблицы, из которых вы хотите получить записи. В предложении FROM должна быть хотя бы одна таблица.
ГДЕ условия
Необязательно. Условия, которые должны быть выполнены для выбора записей.
ORDER BY выражение
Необязательно. Он используется в операторе SELECT LIMIT, чтобы вы могли упорядочить результаты и выбрать те записи, которые хотите вернуть. ASC - это возрастающий порядок, а DESC - убывающий.
LIMIT number_rows
Указывает ограниченное количество строк в результирующем наборе, которое должно быть возвращено, на основе number_rows .Например, LIMIT 10 вернет первые 10 строк, соответствующих критериям SELECT. Здесь порядок сортировки имеет значение, поэтому не забудьте правильно использовать предложение ORDER BY.
OFFSET значение_смещения
Необязательно. Первая строка, возвращаемая LIMIT, будет определяться значением offset_value .

Пример - использование ключевого слова LIMIT

Давайте посмотрим, как использовать оператор SELECT с предложением LIMIT в SQL.

Например:

 ВЫБЕРИТЕ contact_id, last_name, first_name
ИЗ контактов
ГДЕ веб-сайт = 'TechOnTheNet.com '
ЗАКАЗАТЬ ПО contact_id DESC
LIMIT 5; 

В этом примере SQL SELECT LIMIT будут выбраны первые 5 записей из таблицы контактов , где веб-сайт - «TechOnTheNet.com». Обратите внимание, что результаты отсортированы по contact_id в порядке убывания, поэтому это означает, что оператором SELECT LIMIT будет возвращено 5 самых больших значений contact_id .

Если есть другие записи в таблице контактов , у которых есть веб-сайт , значение равно 'TechOnTheNet.com ', они не будут возвращены оператором SELECT LIMIT в SQL.

Если бы мы хотели выбрать 5 наименьших значений contact_id вместо наибольших, мы могли бы изменить порядок сортировки следующим образом:

 ВЫБЕРИТЕ contact_id, last_name, first_name
ИЗ контактов
ГДЕ сайт = 'TechOnTheNet.com'
ЗАКАЗАТЬ ПО contact_id ASC
LIMIT 5; 

Теперь результаты будут отсортированы по contact_id в порядке возрастания, так что первые 5 наименьших записей contact_id , имеющих веб-сайт TechOnTheNet.com 'будет возвращено этим оператором SELECT LIMIT. Никакие другие записи не будут возвращены этим запросом.

Пример - использование ключевого слова OFFSET

Ключевое слово offset позволяет смещать первую запись, возвращаемую предложением LIMIT. Например:

 ПРЕДЕЛ 3 СМЕЩЕНИЕ 1 

Это предложение LIMIT вернет 3 записи в результирующем наборе со смещением 1. Это означает, что оператор SELECT пропустит первую запись, которая обычно будет возвращена, и вместо этого вернет вторую, третью и четвертую записи.

Давайте посмотрим, как использовать оператор SELECT LIMIT с предложением OFFSET в SQL.

Например:

 ВЫБЕРИТЕ contact_id, last_name, first_name
ИЗ контактов
ГДЕ сайт = 'TechOnTheNet.com'
ЗАКАЗАТЬ ПО contact_id DESC
LIMIT 5 OFFSET 2; 

В этом примере SQL SELECT LIMIT используется OFFSET 2, что означает, что первая и вторая записи в наборе результатов будут пропущены ... и затем будут возвращены следующие 5 строк.

Получить подмножество строк, созданных запросом

Резюме : в этом руководстве вы узнаете, как использовать предложение PostgreSQL LIMIT для получения подмножества строк, созданных запросом.

Введение в PostgreSQL Предложение LIMIT

PostgreSQL LIMIT - это необязательный пункт оператора SELECT , который ограничивает количество строк, возвращаемых запросом.

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

 

SELECT select_list FROM table_name ЗАКАЗАТЬ ПО sort_expression LIMIT row_count

Язык кода: SQL (язык структурированных запросов) (sql)

Оператор возвращает row_count строк, сгенерированных запросом.Если row_count равно нулю, запрос возвращает пустой набор. В случае, если row_count равно NULL , запрос возвращает тот же набор результатов, так как он не имеет предложения LIMIT .

Если вы хотите пропустить несколько строк перед возвратом row_count строк, используйте предложение OFFSET , помещенное после предложения LIMIT , как следующий оператор:

 

SELECT select_list FROM table_name LIMIT row_count OFFSET row_to_skip;

Язык кода: SQL (язык структурированных запросов) (sql)

Оператор сначала пропускает row_to_skip строк, а затем возвращает row_count строк, сгенерированных запросом.Если row_to_skip равно нулю, инструкция будет работать так, как будто в ней нет предложения OFFSET .

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

Примеры PostgreSQL LIMIT

Давайте рассмотрим несколько примеров использования предложения PostgreSQL LIMIT .Для демонстрации мы будем использовать таблицу film в базе данных примеров.

1) Использование PostgreSQL LIMIT для ограничения количества возвращаемых строк. Пример

В этом примере используется предложение LIMIT для сортировки первых пяти фильмов по film_id :

 

SELECT film_id, заглавие, release_year ИЗ фильм СОРТИРОВАТЬ ПО film_id LIMIT 5;

Язык кода: SQL (язык структурированных запросов) (sql)

2) Использование PostgreSQL LIMIT с примером OFFSET

Чтобы получить 4 фильма, начиная с четвертого, заказанного с помощью film_id , вы используете как LIMIT , так и OFFSET пункты следующим образом:

 

SELECT film_id, заглавие, release_year ИЗ фильм СОРТИРОВАТЬ ПО film_id LIMIT 4 OFFSET 3;

Язык кода: SQL (язык структурированных запросов) (sql)

3) Использование PostgreSQL LIMIT OFFSSET для получения N строк сверху / снизу

Как правило, вы часто используете предложение LIMIT для выбора строк с наибольшим или нижним числом строк.

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

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

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