it-swarm.com.de

Entspricht LIMIT für DB2

Wie machen Sie LIMIT in DB2 für iSeries? 

Ich habe eine Tabelle mit mehr als 50.000 Datensätzen und möchte Datensätze von 0 bis 10.000 und Datensätze von 10.000 bis 20.000 zurückgeben.

Ich weiß, dass Sie in SQL LIMIT 0,10000 am Ende der Abfrage für 0 bis 10.000 und LIMIT 10000,10000 am Ende der Abfrage für 10.000 bis 20.000 schreiben 

Wie wird das in DB2 gemacht? Was ist der Code und die Syntax? (Beispiel für vollständige Abfrage wird geschätzt)

83
elcool

Entwickelte diese Methode:

Sie benötigen eine Tabelle mit einem eindeutigen Wert, der bestellt werden kann.

Wenn Sie 10.000 bis 25.000 Zeilen haben möchten und Ihre Tabelle 40.000 Zeilen enthält, müssen Sie zunächst den Anfangspunkt und die Gesamtanzahl der Zeilen ermitteln:

int start = 40000 - 10000;

int total = 25000 - 10000;

Und dann übergeben Sie diese per Code an die Abfrage:

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
elcool

FETCH FIRST [n] ROWS ONLY verwenden:

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;

Um Bereiche zu erhalten, müssten Sie ROW_NUMBER() (seit v5r4) und innerhalb der WHERE-Klausel verwenden: (von hier gestohlen: 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;
132
Joe

DB2 für i 7.1 und 7.2 wurde kürzlich um Unterstützung für OFFSET und LIMIT erweitert. Sie benötigen die folgenden DB PTF-Gruppenebenen, um diese Unterstützung zu erhalten:

  • SF99702 Level 9 für IBM i 7.2
  • SF99701 Level 38 für IBM i 7.1

Weitere Informationen finden Sie hier: OFFSET und LIMIT Dokumentation , DB2 für i-Erweiterung Wiki

8
Kevin Adler

Hier ist die Lösung, die ich mir ausgedacht habe:

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

Durch die Initialisierung von LASTVAL auf 0 (oder '' für ein Textfeld) und das anschließende Setzen auf den letzten Wert in der letzten Datensatzgruppe wird die Tabelle in Abschnitten von N Datensätzen durchlaufen.

5
Tom Barron

@ elcools Lösung ist eine clevere Idee, aber Sie müssen die Gesamtzahl der Zeilen kennen (die sich während der Abfrage sogar ändern können!). Ich schlage also eine modifizierte Version vor, die leider 3 Unterabfragen statt 2 benötigt:

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

dabei sollte {last} durch die Zeilennummer des letzten Datensatzes, den ich benötige, ersetzt werden, und {length} sollte durch die Anzahl der benötigten Zeilen ersetzt werden, die als last row - first row + 1 berechnet wird.

Z.B. Wenn ich Zeilen von 10 bis 25 (insgesamt 16 Zeilen) haben möchte, wird {last} 25 und {length} 25-10 + 1 = 16 sein.

2
bluish

Sie sollten auch die Klausel OPTIMIZE FOR n ROWS in Betracht ziehen. Weitere Informationen hierzu finden Sie in der DB2 LUW-Dokumentation im Abschnitt Richtlinien zum Einschränken von SELECT-Anweisungen :

  • Die Klausel OPTIMIZE FOR deklariert die Absicht, nur eine Teilmenge des Ergebnisses abzurufen oder dem Abrufen nur der ersten Zeilen Priorität zu geben. Das Optimierungsprogramm kann dann Zugriffspläne auswählen, die die Antwortzeit für das Abrufen der ersten Zeilen minimieren.
1
David Sky

Versuche dies

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

Es gibt zwei Lösungen zum effizienten Paginieren einer DB2-Tabelle:

1 - Die Technik, die die Funktion row_number () und die Klausel OVER verwendet, die in einem anderen Beitrag dargestellt wurde ("SELECT row_number () OVER (ORDER BY ...)"). An einigen großen Tischen bemerkte ich manchmal eine Leistungsverschlechterung.

2 - die Technik mit einem scrollbaren Cursor. Die Implementierung hängt von der verwendeten Sprache ab. Diese Technik wirkt auf großen Tischen robuster.

Ich habe die zwei in PHP implementierten Techniken während eines Seminars im nächsten Jahr vorgestellt. Die Folie ist unter diesem Link verfügbar: http://gregphplab.com/serendipity/uploads/slides/DB2_PHP_Best_practices.pdf

Sorry, aber dieses Dokument ist nur auf Französisch.

0
gregphplab

Es gibt diese verfügbaren Optionen: -

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
Hector