#sql #pervasive
Вопрос:
Как выполнить подкачку в Pervasive SQL (версия 9.1)? Мне нужно сделать что-то подобное, например:
//MySQL
SELECT foo FROM table LIMIT 10, 10
Но я не могу найти способ определить смещение.
Ответ №1:
Протестированный запрос в PSQL:
select top n *
from tablename
where id not in(
select top k id
from tablename
)
для всех n = количество записей, которые вам нужно получить за один раз.
и k = кратные n(например, n=5; k=0,5,10,15,….)
Ответ №2:
Наша подкачка требовала, чтобы мы могли передать текущий номер страницы и размер страницы (вместе с некоторыми дополнительными параметрами фильтра) в качестве переменных. Так как select top @page_size не работает в MS SQL, мы придумали создать временную или переменную таблицу, чтобы присвоить первичному ключу каждой строки идентификатор, который позже можно будет отфильтровать для нужного номера и размера страницы.
** Обратите внимание, что если у вас есть первичный ключ GUID или составной ключ, вам просто нужно изменить идентификатор объекта во временной таблице на идентификатор uniqueid или добавить дополнительные ключевые столбцы в таблицу.
Недостатком этого является то, что он все равно должен вставить все результаты во временную таблицу, но, по крайней мере, это только ключи. Это работает в MS SQL, но должно работать для любой БД с минимальными настройками.
объявите @page_number int, @page_size int — добавьте любые дополнительные параметры поиска здесь
—создайте временную таблицу со столбцом идентификатора и идентификатором
-записи, которую вы будете выбирать. Это таблица в памяти
, поэтому, если количество строк, которые вы будете вставлять
, превышает 10 000, вместо этого вам следует использовать временную таблицу в базе данных tempdb
. Для этого используйте
—СОЗДАЙТЕ ТАБЛИЦУ #temp_table (ИДЕНТИФИКАТОР row_num int(1,1), objectid int)
—и измените все ссылки на @temp_table на #temp_table
ОБЪЯВИТЕ ТАБЛИЦУ @temp_table (ИДЕНТИФИКАТОР row_num int(1,1), objectid int)—вставьте во временную таблицу идентификаторы записей
, которые мы хотим вернуть. Важно убедиться, что порядок по
-отражает порядок возврата записей, чтобы значения row_num
-были установлены в правильном порядке, и мы выбираем
—правильные записи на основе
ВСТАВКИ страницы В @temp_table (objectid)/* Пример: Выберите, который вставляет записи во временную таблицу
ВЫБЕРИТЕ personid
ИЗ person С (NOLOCK)
внутренней степенью соединения С (NOLOCK) на degree.personid = person.personid
, ГДЕ person.lastname = @last_name
ПОРЯДОК ПО person.lastname asc, person.firsname asc
*/—получить общее количество строк, которые у нас подобраны
объявить @total_rows инт
сет @total_rows = @@rowcount уже
—рассчитает количество страниц на количество
строк, —сочетается и размер листа, переданного в качестве параметра
объявить @total_pages инт
— добавить @размер_страницы — 1, к общему количеству строк
—рассчитает количество страниц. Это связано с тем, что sql
—alwasy округляет для деления целых
чисел НАБОР @total_pages = (@total_rows @page_size — 1) / @page_size—верните интересующий нас результирующий набор, присоединившись
—назад к @temp_table и отфильтровав по номеру строки
/* Пример: Выбор данных для возврата. Если вставка была выполнена
правильно, то вы всегда должны присоединяться к таблице, содержащей
строки для возврата в столбец objectid в @temp_tableВыберите человек.*
От человека с (подсказку nolock) внутреннее соединение @temp_table ТТ
на человека.personid = ТТ.идентификатор ObjectId
*/
—вернуть только те строки, в разделе Что мы заинтересованы в
… и порядка в row_num столбец @temp_table, чтобы убедиться, что
мы-правильный выбор записей
, где ТТ.row_num < (@размер_страницы * @page_number) 1
и TT.row_num > (@размер_страницы * @page_number) — @размер_страницы
заказ по ТТ.row_num
Ответ №3:
Я тоже сталкиваюсь с этой проблемой в MS Sql… без ограничений или функций с номерами строк. Что я делаю, так это вставляю ключи для моего конечного результата запроса (или иногда весь список полей) во временную таблицу со столбцом идентификатора… затем я удаляю из временной таблицы все, что выходит за пределы диапазона, который я хочу… затем использую соединение с ключами и исходной таблицей, чтобы вернуть нужные мне элементы. Это работает, если у вас есть хороший уникальный ключ — если у вас его нет, что ж… это проблема дизайна сама по себе.
Альтернатива с немного лучшей производительностью-пропустить шаг удаления и просто использовать номера строк в вашем окончательном соединении. Еще одним улучшением производительности является использование ВЕРХНЕГО оператора, чтобы, по крайней мере, вам не нужно было хватать материал после окончания того, что вы хотите.
Итак… в псевдокоде… чтобы захватить предметы 80-89…
create table #keys (rownum int identity(1,1), key varchar(10))
insert #keys (key)
select TOP 89 key from myTable ORDER BY whatever
delete #keys where rownumber < 80
select <columns> from #keys join myTable on #keys.key = myTable.key
Ответ №4:
В итоге я сделал подкачку в коде. Я просто пропускаю первые записи в цикле.
Я думал, что придумал простой способ разбиения на страницы, но, похоже, всепроникающий sql не допускает предложений порядка в подзапросах. Но это должно работать на других базах данных (я протестировал это на firebird)
select *
from (select top [rows] * from
(select top [rows * pagenumber] * from mytable order by id)
order by id desc)
order by id