Эквивалент LIMIT для DB2

Как вы делаете LIMIT в DB2 for iSeries?

У меня есть таблица с более чем 50 000 записей, и я хочу вернуть записи от 0 до 10000 и записывать от 10 000 до 20000.

Я знаю, что в SQL вы пишете LIMIT 0,10000 в конце запроса от 0 до 10000 и LIMIT 10000,10000 в конце запроса для 10000 до 20000

Итак, как это делается в DB2? Что такое код и синтаксис? (оценивается полный пример запроса)

Ответ 1

Разработал этот метод:

НУЖНА таблица, которая имеет уникальное значение, которое можно заказать.

Если вам нужны строки от 10 000 до 25 000, а ваша таблица содержит 40 000 строк, сначала вам нужно получить начальную и общую строки:

int start = 40000 - 10000;

int total = 25000 - 10000;

И затем передайте их по коду в запрос:

SELECT * FROM 
(SELECT * FROM schema.mytable 
ORDER BY userId DESC fetch first {start} rows only ) AS mini 
ORDER BY mini.userId ASC fetch first {total} rows only

Ответ 2

Использование FETCH FIRST [n] ROWS ONLY:

http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=/com.ibm.db29.doc.perf/db2z_fetchfirstnrows.htm

SELECT LASTNAME, FIRSTNAME, EMPNO, SALARY
  FROM EMP
  ORDER BY SALARY DESC
  FETCH FIRST 20 ROWS ONLY;

Чтобы получить диапазоны, вам нужно использовать ROW_NUMBER() (начиная с v5r4) и использовать это в предложении WHERE: (украденный здесь: http://www.justskins.com/forums/db2-select-how-to-123209.html)

SELECT code, name, address
FROM ( 
  SELECT row_number() OVER ( ORDER BY code ) AS rid, code, name, address
  FROM contacts
  WHERE name LIKE '%Bob%' 
  ) AS t
WHERE t.rid BETWEEN 20 AND 25;

Ответ 3

Поддержка OFFSET и LIMIT была недавно добавлена в DB2 for я 7.1 и 7.2. Для получения этой поддержки вам понадобятся следующие уровни группы DB PTF:

  • SF99702 уровень 9 для IBM я 7.2
  • SF99701 уровень 38 для IBM я 7.1

Смотрите здесь для получения дополнительной информации: OFFSET и LIMIT документации, DB2 для я Enhancement Wiki

Ответ 4

В этом решении я придумал:

select FIELD from TABLE where FIELD > LASTVAL order by FIELD fetch first N rows only;

Инициализируя LASTVAL до 0 (или '' для текстового поля), затем установите его на последнее значение в самом последнем наборе записей, это будет проходить через таблицу в блоках из N записей.

Ответ 5

решение @elcool - это умная идея, но вам нужно знать общее количество строк (которые могут даже измениться во время выполнения запроса!). Поэтому я предлагаю модифицированную версию, которая, к сожалению, требует 3 подзапроса вместо 2:

select * from (
    select * from (
        select * from MYLIB.MYTABLE
        order by MYID asc 
        fetch first {last} rows only 
        ) I 
    order by MYID desc
    fetch first {length} rows only
    ) II
order by MYID asc

где {last} следует заменить номером строки последней требуемой записи, а {length} следует заменить числом строк, которое мне нужно, вычисленным как last row - first row + 1.

например. если мне нужны строки от 10 до 25 (всего 16 строк), {last} будет 25, а {length} будет 25-10 + 1 = 16.

Ответ 6

Вы также должны рассмотреть предложение OPTIMIZE FOR n ROWS. Подробнее об этом в документации DB2 LUW в Рекомендации по ограничению операторов SELECT topic:

  • Предложение OPTIMIZE FOR объявляет о намерении получить только подмножество результата или предоставить приоритет для извлечения только первых нескольких строк. Затем оптимизатор может выбрать планы доступа, которые минимизируют время отклика для получения первых нескольких строк.

Ответ 7

Существует два решения эффективно разбивать страницы на таблицу DB2:

1 - метод, использующий функцию row_number() и предложение OVER, которое было представлено на другом посту ( "SELECT row_number() OVER (ORDER BY...)" ). На некоторых больших таблицах я иногда замечал ухудшение характеристик.

2 - метод с помощью прокручиваемого курсора. Реализация зависит от используемого языка. Этот метод кажется более надежным на больших таблицах.

Я представил два метода, реализованных в PHP на семинаре в следующем году. Слайд доступен по этой ссылке: http://gregphplab.com/serendipity/uploads/slides/DB2_PHP_Best_practices.pdf

Извините, но этот документ находится только на французском языке.

Ответ 8

Эти доступные варианты: -

DB2 has several strategies to cope with this problem.
You can use the "scrollable cursor" in feature.
In this case you can open a cursor and, instead of re-issuing a query you can FETCH forward and backward.
This works great if your application can hold state since it doesn't require DB2 to rerun the query every time.
You can use the ROW_NUMBER() OLAP function to number rows and then return the subset you want.
This is ANSI SQL 
You can use the ROWNUM pseudo columns which does the same as ROW_NUMBER() but is suitable if you have Oracle skills.
You can use LIMIT and OFFSET if you are more leaning to a mySQL or PostgreSQL dialect.  

Ответ 9

Попробуйте это

SELECT * FROM
    (
        SELECT T.*, ROW_NUMBER() OVER() R FROM TABLE T
    )
    WHERE R BETWEEN 10000 AND 20000