Пейджинг в Pervasive SQL

Как выполнить разбиение по страницам в Pervasive SQL (версия 9.1)? Мне нужно сделать что-то подобное:

//MySQL
SELECT foo FROM table LIMIT 10, 10

Но я не могу найти способ определить смещение.


person Vertigo    schedule 23.09.2008    source источник


Ответы (4)


Протестированный запрос в 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, ....)

person Vijay Bobba    schedule 11.05.2010

Наше разбиение на страницы требовало, чтобы мы могли передавать текущий номер страницы и размер страницы (вместе с некоторыми дополнительными параметрами фильтра) в качестве переменных. Поскольку select top @page_size не работает в MS SQL, мы придумали создать временную таблицу или таблицу переменных, чтобы присвоить каждому первичному ключу строк идентификатор, который впоследствии можно будет отфильтровать по желаемому номеру и размеру страницы.

** Обратите внимание, что если у вас есть первичный ключ GUID или составной ключ, вам просто нужно изменить идентификатор объекта во временной таблице на уникальный идентификатор или добавить в таблицу дополнительные ключевые столбцы.

Обратной стороной этого является то, что он все равно должен вставить все результаты во временную таблицу, но, по крайней мере, это только ключи. Это работает в MS SQL, но должно работать для любой БД с минимальными настройками.

объявить @page_number int, @page_size int - добавить сюда любые дополнительные параметры поиска

--создайте временную таблицу со столбцом идентификаторов и идентификатором
записи, которую вы будете выбирать. Это
--таблица в памяти, поэтому, если количество вставляемых строк больше
- чем 10 000, вам следует использовать временную таблицу в tempdb
- вместо. Для этого используйте
--CREATE TABLE #temp_table (row_num int IDENTITY (1,1), objectid int)
- и измените все ссылки с @temp_table на #temp_table
DECLARE @temp_table ТАБЛИЦА (row_num int IDENTITY (1,1), objectid int)

- вставить во временную таблицу с идентификаторами записей
- мы хотим вернуть. Очень важно убедиться, что порядок по
- отражает порядок возвращаемых записей, чтобы значения row_num
были установлены в правильном порядке, и мы выбираем
- правильные записи на основе страницы
INSERT INTO @temp_table (objectid)

/ * Пример: выберите, который вставляет записи во временную таблицу
SELECT personid
FROM person WITH (NOLOCK)
степень внутреннего соединения WITH (NOLOCK) на degree.personid = person.personid
ГДЕ person.lastname = @last_name
ЗАКАЗАТЬ ПО person.lastname asc, person.firsname asc
* /

- получить общее количество сопоставленных строк
DECLARE @total_rows int
SET @total_rows = @@ ROWCOUNT
- вычислить общее количество страниц на основе количества
- совпавшие строки и размер страницы, переданный в качестве параметра
DECLARE @total_pages int
--добавьте @page_size - 1 к общему количеству строк, чтобы
- вычислить общее количество страниц. Это потому, что sql
--alwasy округляет в меньшую сторону для деления целых чисел
SET @total_pages = (@total_rows + @page_size - 1) / @page_size

- вернуть интересующий нас набор результатов путем присоединения
--back к @temp_table и фильтрации по row_num
/ * Пример: выбор данных для возврата. Если вставка была
выполнена правильно, вы всегда должны присоединяться к таблице, которая содержит
строки, чтобы вернуться в столбец objectid в @temp_table.

ВЫБРАТЬ человека. *
ОТ человека С (NOLOCK) INNER JOIN @temp_table tt
ON person.personid = tt.objectid
* /
- вернуть только строки на странице что нас интересует
- и упорядочить по столбцу row_num в @temp_table, чтобы убедиться,
- мы выбираем правильные записи
WHERE tt.row_num ‹(@page_size * @ page_number) + 1
И tt.row_num> (@page_size * @page_number) - @page_size
ЗАКАЗАТЬ ПО tt.row_num

person jjacka    schedule 10.10.2008

Я тоже сталкиваюсь с этой проблемой в MS Sql ... нет функций Limit или rownumber. Что я делаю, так это вставляю ключи для моего окончательного результата запроса (или иногда всего списка полей) во временную таблицу со столбцом идентификаторов ... затем я удаляю из временной таблицы все, что находится за пределами диапазона, который я хочу ... затем использую соединение ключей и исходной таблицы, чтобы вернуть нужные мне предметы. Это работает, если у вас есть хороший уникальный ключ - если нет, ну ... это проблема дизайна сама по себе.

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

Итак ... в псевдокоде ... чтобы получить элементы 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
person Jasmine    schedule 23.09.2008

Я закончил тем, что сделал подкачку кода. Я просто пропускаю первые записи в цикле.

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

select *
from (select top [rows] * from
(select top [rows * pagenumber] * from mytable order by id)
order by id desc)
order by id
person Vertigo    schedule 13.10.2008