Immer wieder benötigt an eine Möglichkeit, um nur eine bestimmte Anzahl von Datensätzen zu selektieren. Man hat zum Beispiel eine Liste in der die Daten nur bei Bedarf geholt werden sollen. Anfangs nur 25 Datensätze, wenn man ans Ende der Liste gescrollt hat, sollen die nächsten 25 Datensätze geholt werden. Gerade bei Webanwendungen ist das oft notwendig, wenn man in einer Liste sehr viele Daten anzeigen will.

Nur wie sieht das entsprechende SQL-Statement dafür aus? Die meisten Datenbanken bieten Mechanismen dafür an. Gerade, wenn es sich um Datenbanken handelt, die für die Verwendung im Internet optimiert sind. Folgende Befehle hab ich dafür schon gesehen:

SELECT TOP 25 * FROM [EMP];
SELECT TOP 25 START AT 25 * FROM [EMP];
...

oder

SELECT * FROM [EMP] LIMIT 0,25;
SELECT * FROM [EMP] LIMIT 25,25;
...

Doch was, wenn es keine solche Syntax gibt? Für den Azure SQL-Server scheint dies der Fall zu sein. Zumindest hab ich keine funktionierende Syntax gefunden. Aber schließlich gibt es für alles eine Lösung (auch wenn mir diese Lösung nicht wirklich gefällt.

Die Idee dahinter ist relativ einfach. Mit TOP kann man auf eine bestimmte Anzahl von Datensätzen einschränken. Aber wie erklär ich der Datenbank, dass erst ab einem bestimmten Datensatz begonnen werden soll? Naja.. Indem man eben die ersten Datensätze wieder ausnimmt.

Das Ganze sieht dann so aus:

SELECT TOP 25 * FROM [EMP];
SELECT TOP 25 * FROM [EMP] WHERE [ID] NOT IN (SELECT TOP 24 [ID] FROM [EMP]);
SELECT TOP 25 * FROM [EMP] WHERE [ID] NOT IN (SELECT TOP 49 [ID] FROM [EMP]);
...

In einem Subselect werden also alle nicht benötigten Datensätze gleich im Vorfeld wieder ausgefiltert.

Wie gesagt… Die Lösung gefällt mir selbst nicht unbedingt, aber sie funktioniert.

 

Edit 24.07.2012:

es gibt doch immer eine bessere Lösung. Jetzt sogar eine, die auch mir gefällt. Allerdings muss man dazu sagen, dass diese Lösung nur mit SQLServer 2012 funktioniert, was aber in meinem Fall kein Problem ist, da bei Azure ohnehin die 2012er Version läuft.

Also, was hat Microsoft sich einfallen lassen. An den obigen Beispiel sieht man ja schon, dass da scheinbar jeder Hersteller sein eigenes Süppchen kocht und so hat auch Microsoft mit dem SQLServer 2012 eine Technik eingeführt, die ich sonst noch nicht gesehen habe. Aber sie ist dafür auch leicht verständlich.

SELECT * FROM [EMP] OFFSET 0 ROWS FETCH NEXT 25 ROWS ONLY;
SELECT * FROM [EMP] OFFSET 25 FETCH NEXT 25 ROWS ONLY;

Man gibt also lediglich den Offset an, ab dem die Daten gelesen werden sollen und dann noch, dass nur die nächsten 25 Zeilen geholt werden sollen. Es ist zwar relativ viel zu schreiben und es wieder eines der Statements, bei denen ich das Gefühl habe, mit dem Computer zu reden, aber es funktioniert… und das ist wichtig.