Ich bin daran interessiert, einige (idealerweise) datenbankunabhängige Methoden zur Auswahl der n- ten Zeile aus einer Datenbanktabelle zu lernen . Es wäre auch interessant zu sehen, wie dies mit der nativen Funktionalität der folgenden Datenbanken erreicht werden kann:
- SQL Server
- MySQL
- PostgreSQL
- SQLite
- Orakel
Ich mache derzeit in SQL Server 2005 so etwas wie das Folgende, aber ich wäre daran interessiert, die agnostischeren Ansätze anderer zu sehen:
WITH Ordered AS (
SELECT ROW_NUMBER() OVER (ORDER BY OrderID) AS RowNumber, OrderID, OrderDate
FROM Orders)
SELECT *
FROM Ordered
WHERE RowNumber = 1000000
Gutschrift für das oben genannte SQL: Firoz Ansaris Weblog
Update: Siehe Troels Arvins Antwort zum SQL-Standard. Troels, hast du irgendwelche Links, die wir zitieren können?
OrderNo N
, fügen Sie eine OrderSequenceNo- Spalte in die Tabelle ein und generieren Sie sie beim Erstellen einer neuen Bestellung aus einem unabhängigen Sequenzgenerator .offset x fetch first y rows only
. Wird derzeit von (mindestens) Postgres, Oracle12, DB2 unterstützt.Antworten:
Es gibt Möglichkeiten, dies in optionalen Teilen des Standards zu tun, aber viele Datenbanken unterstützen ihre eigene Vorgehensweise.
Eine wirklich gute Seite, die über dieses und andere Dinge spricht, ist http://troels.arvin.dk/db/rdbms/#select-limit .
Grundsätzlich unterstützen PostgreSQL und MySQL das Nicht-Standard:
Oracle, DB2 und MSSQL unterstützen die Standardfensterfunktionen:
(die ich gerade von der oben verlinkten Seite kopiert habe, da ich diese DBs nie benutze)
Update: Ab PostgreSQL 8.4 werden die Standardfensterfunktionen unterstützt. Erwarten Sie daher, dass das zweite Beispiel auch für PostgreSQL funktioniert.
Update: SQLite hat am 15.09.2018 Unterstützung für Fensterfunktionen in Version 3.25.0 hinzugefügt, sodass beide Formulare auch in SQLite funktionieren.
quelle
WHERE rownumber = n
nur die n-te Reihe sein?PostgreSQL unterstützt Fensterfunktionen, wie sie im SQL-Standard definiert sind, aber sie sind umständlich, sodass die meisten Benutzer (den Nicht-Standard)
LIMIT
/ verwendenOFFSET
:In diesem Beispiel wird die 21. Zeile ausgewählt.
OFFSET 20
fordert Postgres auf, die ersten 20 Datensätze zu überspringen. Wenn Sie keineORDER BY
Klausel angeben , gibt es keine Garantie dafür, welchen Datensatz Sie zurückerhalten, was selten nützlich ist.quelle
Ich bin mir über den Rest nicht sicher, aber ich weiß, dass SQLite und MySQL keine "Standard" -Zeilenreihenfolge haben. Zumindest in diesen beiden Dialekten erfasst das folgende Snippet den 15. Eintrag aus der Tabelle und sortiert nach dem Datum / der Uhrzeit, zu der es hinzugefügt wurde:
(Natürlich müssten Sie ein DATETIME-Feld hinzufügen und es auf das Datum / die Uhrzeit einstellen, zu der der Eintrag hinzugefügt wurde ...)
quelle
In SQL 2005 und höher ist diese Funktion integriert. Verwenden Sie die Funktion ROW_NUMBER (). Es eignet sich hervorragend für Webseiten mit einem Browsing im Stil << Zurück und Weiter >>:
Syntax:
quelle
Ich vermute, dass dies äußerst ineffizient ist, aber ein recht einfacher Ansatz ist, der an einem kleinen Datensatz funktioniert hat, an dem ich ihn ausprobiert habe.
Dies würde den 5. Artikel erhalten, die zweite Top-Nummer ändern, um einen anderen n-ten Artikel zu erhalten
Nur SQL Server (glaube ich), sollte aber auf älteren Versionen funktionieren, die ROW_NUMBER () nicht unterstützen.
quelle
1 kleine Änderung: n-1 statt n.
quelle
Überprüfen Sie es auf SQL Server:
Dies gibt Ihnen die 10. REIHE der Emp-Tabelle!
quelle
Im Gegensatz zu einigen Antworten schweigt der SQL-Standard zu diesem Thema nicht.
Seit SQL: 2003 können Sie "Fensterfunktionen" verwenden, um Zeilen zu überspringen und Ergebnismengen einzuschränken.
In SQL: 2008 wurde ein etwas einfacherer Ansatz hinzugefügt
OFFSET skip ROWS FETCH FIRST n ROWS ONLY
Persönlich glaube ich nicht, dass die Hinzufügung von SQL: 2008 wirklich notwendig war. Wenn ich also ISO wäre, hätte ich es aus einem bereits ziemlich großen Standard herausgehalten.
quelle
Als wir in MSSQL 2000 gearbeitet haben, haben wir das gemacht, was wir "Triple-Flip" genannt haben:
BEARBEITET
Es war nicht elegant und nicht schnell, aber es funktionierte.
quelle
IF / ELSE IF
Blöcke unter derOuterPageSize
Berechnung - auf den Seiten 1 und 2 wird derOuterPageSize
Wert auf 10 zurückgesetzt. Auf Seite 3 (Zeilen 21-25) gibt die Berechnung korrekt 5 zurück und auf allen Seiten 4 und höher. Das negative Ergebnis der Berechnung wird durch 0 ersetzt (obwohl es wahrscheinlich nur schneller wäre, eine leere Datenzeile sofort an diesem Punkt zurückzugeben).Wählen Sie den n-ten Datensatz von oben aus
Wählen Sie den n-ten Datensatz von unten aus
quelle
Orakel:
quelle
where ROWNUM = x
funktioniert nur für x = 1 in Oracle DB. dh eswhere ROWNUM = 2
werden keine Zeilen zurückgegeben.In Oracle 12c können Sie die
OFFSET..FETCH..ROWS
Option mit verwendenORDER BY
Zum Beispiel, um den 3. Datensatz von oben zu erhalten:
quelle
Hier ist eine schnelle Lösung Ihrer Verwirrung.
Hier können Sie die letzte Zeile durch Füllen von N = 0, die vorletzte durch N = 1, die vierte letzte durch Füllen von N = 3 usw. erhalten.
Dies ist eine sehr häufige Frage während des Interviews und dies ist eine sehr einfache Antwort darauf.
Weiter Wenn Sie Betrag, ID oder eine numerische Sortierreihenfolge wünschen, können Sie sich für die CAST-Funktion in MySQL entscheiden.
Hier Durch Ausfüllen von N = 4 können Sie die fünftletzte Aufzeichnung der höchsten Menge aus der CART-Tabelle erhalten. Sie können Ihren Feld- und Tabellennamen anpassen und eine Lösung finden.
quelle
HINZUFÜGEN:
Dadurch werden die Ergebnisse ab Ergebnis n auf ein Ergebnis begrenzt.
quelle
Wenn Sie beispielsweise jede 10. Zeile in MSSQL auswählen möchten, können Sie Folgendes verwenden:
Nehmen Sie einfach den MOD und ändern Sie hier die Nummer 10 nach Belieben.
quelle
Für SQL Server ist ein generischer Weg, nach Zeilennummer zu gehen, wie folgt:
Zum Beispiel:
Dies gibt die Informationen der 20. Zeile zurück. Stellen Sie sicher, dass Sie danach die Zeilenanzahl 0 eingeben.
quelle
LIMIT n, 1 funktioniert in MS SQL Server nicht. Ich denke, es ist nur die einzige große Datenbank, die diese Syntax nicht unterstützt. Um fair zu sein, ist es nicht Teil des SQL-Standards, obwohl es so weit verbreitet ist, dass es sein sollte. In allem außer SQL Server funktioniert LIMIT hervorragend. Für SQL Server konnte ich keine elegante Lösung finden.
quelle
Hier ist eine generische Version eines Sproc, den ich kürzlich für Oracle geschrieben habe und der dynamisches Paging / Sortieren ermöglicht - HTH
quelle
Aber wirklich, ist das nicht wirklich nur ein Salon-Trick für ein gutes Datenbankdesign? Die wenigen Male, die ich solche Funktionen benötigte, war es für eine einfache einmalige Abfrage, einen schnellen Bericht zu erstellen. Für jede echte Arbeit führt die Verwendung solcher Tricks zu Problemen. Wenn die Auswahl einer bestimmten Zeile erforderlich ist, haben Sie einfach eine Spalte mit einem sequentiellen Wert und fertig.
quelle
Für SQL Server wird im Folgenden die erste Zeile aus der angegebenen Tabelle zurückgegeben.
Sie können die Werte folgendermaßen durchlaufen:
quelle
In Sybase SQL Anywhere:
Vergessen Sie nicht die Bestellung von oder es ist bedeutungslos.
quelle
T-SQL - Auswahl der N-ten Datensatznummer aus einer Tabelle
Um beispielsweise den 5. Datensatz aus einer Tabelle Mitarbeiter auszuwählen, sollte Ihre Abfrage lauten
quelle
quelle
Ich habe diese Abfrage geschrieben, um die N-te Zeile zu finden. Beispiel mit dieser Abfrage wäre
quelle
Es ist unglaublich, dass Sie eine SQL-Engine finden, die diese ausführt ...
quelle
Nichts Besonderes, keine besonderen Funktionen, falls Sie Caché wie ich verwenden ...
Vorausgesetzt, Sie haben eine ID-Spalte oder eine Datenstempelspalte, der Sie vertrauen können.
quelle
So würde ich es in DB2 SQL machen. Ich glaube, die RRN (relative Datensatznummer) wird vom Betriebssystem in der Tabelle gespeichert.
quelle
Wählen Sie zuerst die obersten 100 Zeilen in aufsteigender Reihenfolge und dann die letzte Zeile in absteigender Reihenfolge und begrenzen Sie sie auf 1. Dies ist jedoch eine sehr teure Aussage, da zweimal auf die Daten zugegriffen wird.
quelle
Es scheint mir, dass Sie, um effizient zu sein, 1) eine Zufallszahl zwischen 0 und eins weniger als die Anzahl der Datenbankeinträge generieren müssen und 2) die Zeile an dieser Position auswählen können. Leider haben verschiedene Datenbanken unterschiedliche Zufallszahlengeneratoren und unterschiedliche Möglichkeiten, eine Zeile an einer Position in einer Ergebnismenge auszuwählen. Normalerweise geben Sie an, wie viele Zeilen übersprungen werden sollen und wie viele Zeilen Sie möchten. Für verschiedene Datenbanken wird dies jedoch unterschiedlich ausgeführt. Hier ist etwas, das für mich in SQLite funktioniert:
Es hängt davon ab, ob eine Unterabfrage in der Limit-Klausel verwendet werden kann (in SQLite LIMIT <zu überspringende Recs>, <zu nehmende Recs>). Die Auswahl der Anzahl der Datensätze in einer Tabelle sollte besonders effizient sein und Teil der Datenbank sein Metadaten, aber das hängt von der Implementierung der Datenbank ab. Ich weiß auch nicht, ob die Abfrage tatsächlich die Ergebnismenge erstellt, bevor der N-te Datensatz abgerufen wird, aber ich würde hoffen, dass dies nicht erforderlich ist. Beachten Sie, dass ich keine "order by" -Klausel spezifiziere. Es ist möglicherweise besser, nach dem Primärschlüssel zu "ordnen", der einen Index enthält. Das Abrufen des N-ten Datensatzes aus einem Index ist möglicherweise schneller, wenn die Datenbank den N-ten Datensatz nicht aus der Datenbank selbst abrufen kann, ohne die Ergebnismenge zu erstellen .
quelle
Die am besten geeignete Antwort, die ich in diesem Artikel für SQL Server gesehen habe
quelle