Пейджинг в распространенном SQL - PullRequest
0 голосов
/ 23 сентября 2008

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

//MySQL
SELECT foo FROM table LIMIT 10, 10

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

Ответы [ 4 ]

2 голосов
/ 11 мая 2010

Протестированный запрос в PSQL:

select top n * 
from tablename 
where id not in(
select top k id
from tablename 
) 

для всех n = no.of записей, которые вам нужно получить за раз. и k = кратное n (например, n = 5; k = 0,5,10,15, ....)

1 голос
/ 10 октября 2008

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

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

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

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

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

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

/ * Пример: выберите, что вставляет записи во временную таблицу
ВЫБЕРИТЕ персону
ОТ ЛИЦА С (NOLOCK)
степень внутреннего соединения с (NOLOCK) на степень.персонала = person.personid
ГДЕ person.lastname = @last_name
ЗАКАЗАТЬ ЛИЦА.Имя АСС, person.firsname asc
* /

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

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

ВЫБРАТЬ человека. *
ОТ человека С (NOLOCK) ВНУТРЕННЕЕ СОЕДИНЕНИЕ @temp_table tt
ON person.personid = tt.objectid
* /
- вернуть только те строки на интересующей нас странице
- и упорядочить по столбцу row_num @temp_table, чтобы убедиться, что
- мы выбираем правильные записи
ГДЕ tt.row_num < (@page_size * @page_number) + 1
AND tt.row_num> (@page_size * @page_number) - @page_size
ЗАКАЗАТЬ BY tt.row_num

0 голосов
/ 13 октября 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
0 голосов
/ 23 сентября 2008

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

Альтернатива с немного лучшей производительностью - пропустить шаг удаления и просто использовать номера строк в вашем последнем соединении. Еще одним улучшением производительности является использование оператора 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
...