Ekwiwalent limitu dla DB2

Jak zrobić LIMIT W DB2 dla iSeries?

Mam tabelę z ponad 50 000 rekordów i chcę zwrócić rekordy od 0 do 10 000 i rekordy od 10 000 do 20 000.

Wiem, że w SQL piszesz LIMIT 0,10000 na końcu zapytania od 0 do 10 000 i LIMIT 10000,10000 na końcu zapytania od 10000 do 20 000

Jak to się robi w DB2? Jaki jest kod i składnia? (przykład pełnego zapytania jest mile widziany)
Author: elcool, 2010-10-07

9 answers

Używając 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;

Aby uzyskać zakresy, musisz użyć ROW_NUMBER() (od v5r4) i użyć tego w WHERE klauzuli: (skradzione stąd: 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;
 130
Author: Joe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-05 08:24:31

Opracował tę metodę:

Potrzebujesz tabeli, która ma unikalną wartość, którą można zamówić.

Jeśli chcesz wiersze od 10 000 do 25 000, a twoja tabela ma 40 000 wierszy, najpierw musisz uzyskać punkt początkowy i liczbę wierszy:

int start = 40000 - 10000;

int total = 25000 - 10000;

A następnie przekaż je kodem do zapytania:

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
 12
Author: elcool,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-07 20:06:51

Wsparcie dla offsetu i limitu zostało ostatnio dodane do DB2 dla i 7.1 i 7.2. Aby uzyskać wsparcie, potrzebujesz następujących poziomów grupy DB PTF:

  • SF99702 poziom 9 dla IBM i 7.2
  • SF99701 Poziom 38 dla IBM i 7.1

Zobacz tutaj, aby uzyskać więcej informacji: OFFSET i LIMIT dokumentacja , DB2 dla i Enhancement Wiki

 8
Author: Kevin Adler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-04 22:23:56

Oto rozwiązanie, które wymyśliłem:

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

Inicjując lastval na 0( lub " dla pola tekstowego), a następnie ustawiając go na ostatnią wartość w najnowszym zestawie rekordów, spowoduje to przejście przez tabelę w kawałkach N rekordów.

 5
Author: Tom Barron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-11 19:18:24

@rozwiązanie elcool jest sprytnym pomysłem, ale musisz znać całkowitą liczbę wierszy (które mogą się nawet zmienić podczas wykonywania zapytania!). Proponuję więc zmodyfikowaną wersję, która niestety wymaga 3 zapytań podrzędnych zamiast 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

Gdzie {[1] } należy zastąpić numerem wiersza ostatniego rekordu, którego potrzebuję, a {[2] } należy zastąpić liczbą wierszy, których potrzebuję, obliczoną jako last row - first row + 1.

Np. jeśli chcę wiersze od 10 do 25 (całkowicie 16 wierszy), {last} będzie 25 i {length} będzie 25-10+1=16.

 2
Author: bluish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:16

Należy również rozważyć klauzulę OPTIMIZE FOR n ROWS. Więcej szczegółów na ten temat można znaleźć w dokumentacji DB2 LUW w Guidelines for restricting SELECT statements topic:

  • klauzula OPTIMIZE FOR deklaruje zamiar pobrania tylko podzbioru wyniku lub nadania priorytetu pobieraniu tylko kilku pierwszych wierszy. Optymalizator może następnie wybrać plany dostępu, które minimalizują czas reakcji na pobranie pierwszych kilku wierszy.
 0
Author: David Sky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-08 15:26:37

Istnieją 2 rozwiązania do wydajnej paginacji w tabeli DB2:

1-technika wykorzystująca funkcję row_number () i klauzulę, nad którą została przedstawiona w innym poście ("SELECT row_number () OVER (ORDER BY ... )"). Na niektórych dużych stołach zauważyłem czasami degradację występów.

2-technika wykorzystująca przewijalny kursor. Implementacja zależy od używanego języka. Ta technika wydaje się bardziej wytrzymała na dużych stołach.

Przedstawiłem 2 techniki zaimplementowane w PHP podczas seminarium w przyszłym roku. Slajd jest dostępny pod tym linkiem : http://gregphplab.com/serendipity/uploads/slides/DB2_PHP_Best_practices.pdf

Przepraszamy, ale ten dokument jest tylko w języku francuskim.

 0
Author: gregphplab,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-05 11:04:42

Dostępne są następujące opcje: -

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
Author: Hector,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-03 11:53:50

Spróbuj tego

SELECT * FROM
    (
        SELECT T.*, ROW_NUMBER() OVER() R FROM TABLE T
    )
    WHERE R BETWEEN 10000 AND 20000
 0
Author: Lucio Menci,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-19 15:18:06