Wie wählt man die n-te Zeile und n folgende Zeilen einer Tabelle aus?

Aus DBWiki
Wechseln zu: Navigation, Suche

Anforderung

Du willst aus einer Tabelle oder Auswahlabfrage ab einem bestimmten Zeilenoffset eine bestimmte Anzahl Datensätze auswählen.

Lösung

Einige SQL-Dialekte haben mittlerweile die Standard-Klazusel FETCH FIRST mit Angabe eines Offsets implementiert. Andere verwenden eine LIMIT-Klausel o.ä. mit der gleichen Funktionalität - nur unter anderem Namen. Damit lässt sich die Aufgabe einfach lösen, indem man entsprechende Zahlenwerte für die Anzahl der Datensätze und des Offsets angibt.


In Microsoft Access gestaltet sich eine Lösung schwieriger und auch umständlicher, weil dem TOP-Prädikat (Spitzenwerte) eine Offset-Klausel fehlt. Zuerst muss sichergestellt werden, dass die Daten in der gewünschten Sortierung vorliegen. Bei Tabellen mit Primärschlüssel wird dieser ohne weitere Angabe immer in aufsteigender Reihenfolge verwendet. Fehlt ein Primärschlüssel oder will man eine andere Sortierung als Basis für die Auswahl haben oder beruht die Basis der Daten auf einer Auswahlabfrage, muss man immer eine Sortierung in der Abfrage angeben. Zusätzlich gilt zu beachten, dass nicht eindeutige Datensätze auch mehr Ergebnisdatensätze, als im TOP-Prädikat angegeben wurde, liefern können. Um z. Bsp. aus einer großen Personentabelle die Datensätze 101 - 150 auszugeben, kann wie folgt vorgegangen werden (unterstellt, dass die Feldliste Nachname, Vorname und Geburtsdatum eindeutige Datensätze liefert und aus Performance-Gründen ein mehrdeutiger Index in gleicher Reihenfolge vorliegt).

in Jet-SQL

SELECT TOP 50
       p.*
FROM   personal AS p
       LEFT JOIN (SELECT TOP 100
                         nachname,
                         vorname,
                         gebdatum
                  FRPM   personal
                  ORDER BY 1, 2, 3) AS q
              ON (p.nachname = q.nachname) AND
                 (p.vorname  = q.vorname)  AND
                 (p.gebdatum = q.gebdatum)
WHERE  q.nachname IS NULL
ORDER  BY p.nachname, p.vorname, p.gebdatum
Wiki hinweis.png Anmerkung:
Ein kleiner Wermutstropfen bei der Lösung ist, dass der Wert hinter dem TOP-Pädikat nicht als Parameter verwendet werden kann und der Abfragetext bei sich ändernder Anforderungen angepasst werden muss.


in SQLite3, PostgreSQL, ...

SELECT *
FROM   personal
ORDER  BY nachname, vorname, gebdatum
LIMIT  50 OFFSET 100  -- alternativ in SQLite3 auch: LIMIT 100, 50 -- (Achtung: vertauschte Reihenfolge)