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

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

84 голосов
/ 07 октября 2010

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

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

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

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

Ответы [ 9 ]

133 голосов
/ 07 октября 2010

Использование 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;
12 голосов
/ 08 октября 2010

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

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

Если вы хотите, чтобы строки были от 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
8 голосов
/ 05 февраля 2016

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

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

Дополнительную информацию смотрите здесь: OFFSET and LIMIT Документация , DB2 for i Enhancement Wiki

5 голосов
/ 11 февраля 2014

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

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

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

2 голосов
/ 05 июня 2012

@ elcool's решение - разумная идея, но вам нужно знать общее количество строк (которое может даже измениться во время выполнения запроса!). Поэтому я предлагаю модифицированную версию, которая, к сожалению, нуждается в 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.

1 голос
/ 19 октября 2017

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

SELECT * FROM
    (
        SELECT T.*, ROW_NUMBER() OVER() R FROM TABLE T
    )
    WHERE R BETWEEN 10000 AND 20000
1 голос
/ 08 октября 2010

Вы также должны рассмотреть предложение ОПТИМИЗИРОВАТЬ ДЛЯ n СТРОК. Более подробную информацию обо всем этом можно найти в документации по DB2 LUW в Указаниях по ограничению операторов SELECT topic:

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

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

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.  
0 голосов
/ 05 марта 2013

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...