Können Sie uns die Reihenfolge mitteilen, nach der Sie "Top 1" möchten?
Andrew Wolfe
1
Zuallererst sollten Sie sich niemals auf die DB-Engine verlassen, um dies zu tun. Wenn Sie solche Dinge wissen möchten, setzen Sie einen Sequenzer ein. Wenn Sie dies tun, wird garantiert, dass sie in der Reihenfolge nummeriert werden, in der sie eingefügt wurden.
Dies ist gut, wenn Sie nur 1 Zeile möchten und es egal ist, welche. Wenn Sie bestimmte Zeilen wie den letzten Datensatz möchten, müssen Sie die Sortierung in einer Unterauswahl durchführen, wie z. B. die Antwort von Vash. Oracle weist vor der Sortierung Rownums zu.
Scott Bailey
4
@ Scott yup. das ist richtig. Und Patrick, guter Punkt, ich denke, die Syntax ist in dieser Hinsicht falsch. Es sollte wirklich ein Keep Over sein (dens_rank () last ...)
mcpeterson
2
Der Unterschied zwischen dem ersten und dem zweiten Beispiel besteht darin, dass das erste eine Zeile auswählt (eine beliebige Zeile ohne Reihenfolge). Das zweite Beispiel erhält den Wert der ersten Zeile, ohne eine innere Abfrage der Reihenfolge durchzuführen (wie in den folgenden Beispielen gezeigt).
JulesLt
3
Die Syntax ist nicht korrekt in: Wählen Sie max (fname) über (rank () order by some_factor) von MyTbl
Stéphane Gerber
1
@jclozano "keine sehr bekannte Funktionalität von Orakel" - In Bezug auf Respekt bitte ich zu unterscheiden. Dies ist wichtig, da "nicht bekannte Funktionen" dazu neigen, Unklarheiten zu implizieren, und daher vorschlagen könnten, dass wir die Verwendung vermeiden sollten. Dies ist nicht unklar, und seine Verwendung sollte nicht vermieden werden.
Interessanter Befehl, ich verwende hier 12c und das ist OFFSET 0 ROWSanscheinend nicht notwendig, Sie können verwenden FETCH NEXT 1 ROWS ONLYoder sogar FETCH FIRST ROW ONLY, die Reihenfolge nach ist wichtig oder es wird gleichbedeutend sein, nur a zu verwenden WHERE rownum = 1. Ich habe es sogar in einer OUTER APPLY-Anweisung versucht und es hat dort wie die TOP-Funktion von Ms-SQL funktioniert.
Rafael Merlin
Sie haben Recht @RafaelMerlin. Nach Ihrem Beitrag habe ich erkannt, dass OFFSET 0 ROWS nicht erforderlich ist. Es wäre nützlich, wenn Daten zwischen Top X und Top Y abgerufen werden.
So weit so gut, mit einem wichtigen fehlenden Punkt, der ist TIES. Siehe dies für die Fälle , in denen Bindungen auftreten für Version 12c +und12c -
Barbaros Özhan
10
Sie können ROW_NUMBER()eine ORDER BYKlausel in der Unterabfrage verwenden und diese Spalte anstelle von verwenden TOP N. Dies kann Schritt für Schritt erklärt werden.
Siehe die folgende Tabelle mit zwei Spalten NAMEund DT_CREATED.
Wenn Sie unabhängig davon nur die ersten beiden Daten verwenden müssen NAME, können Sie die folgende Abfrage verwenden. Die Logik wurde in die Abfrage geschrieben
-- The number of records can be specified in WHERE clauseSELECT RNO,NAME,DT_CREATED
FROM(-- Generates numbers in a column in sequence in the order of dateSELECT ROW_NUMBER()OVER(ORDERBY DT_CREATED)AS RNO,
NAME,DT_CREATED
FROM DEMOTOP
)TAB
WHERE RNO<3;
ERGEBNIS
In einigen Situationen müssen wir die TOP Njeweiligen Ergebnisse auswählen NAME. In diesem Fall können wir PARTITION BYmit einer ORDER BYKlausel in der Unterabfrage verwenden. Beziehen Sie sich auf die folgende Abfrage.
-- The number of records can be specified in WHERE clauseSELECT RNO,NAME,DT_CREATED
FROM(--Generates numbers in a column in sequence in the order of date for each NAMESELECT ROW_NUMBER()OVER(PARTITIONBY NAME ORDERBY DT_CREATED)AS RNO,
NAME,DT_CREATED
FROM DEMOTOP
)TAB
WHERE RNO<3;
Die Verwendung von ROW_NUMBER () ... ist eine korrektere Lösung als in der Themenantwort. Ein Problem mit dieser Lösung (und auch mit der max (Feld) -Variante), dass Sie Dinge wie "select ... (select ROW_NUMBER () ...) for update ;" nicht ausführen können ;
Alexo Po.
Und es ist manchmal sehr wichtig in PL / SQL (leider konnte der vorherige Kommentar nicht innerhalb von 5 Minuten bearbeitet werden).
Alexo Po.
In diesem Fall können wir CTE wie im äußeren Teil verwenden. Richtig? @ Alexo Po.
Sarath Avanavu
Ich glaube ich verstehe dich nicht. Die for update- Klausel kann verwendet werden, wenn ROWID von Oracle "leicht" beibehalten wird. Das Gruppieren (und das Gruppieren aufgrund der Verwendung von Analyseklauseln) verbirgt also echte ROWID und Zeilen können nicht gesperrt werden. Und zweitens with (select ... ) as ändert CTE ( Klausel) nichts an diesem Problem. CTE zielt nur darauf ab, Abfragen zu lesen und zu unterstützen. Richtig? @ Sarath Avanavu
Alexo Po.
Notiz an mich. Das Problem mit ROWID tritt tatsächlich speziell aufgrund der Bedingung RNO <3 auf. In diesem Fall ist der Wert von RNO nicht mit ROWID verbunden, sodass Oracle keine Zeilen sperren kann.
Alexo Po.
9
Sie können so etwas tun
SELECT*FROM(SELECT Fname FROM MyTbl ORDERBY Fname )WHERE rownum =1;
Sie können auch die Analysefunktionen RANK und / oder DENSE_RANK verwenden , aber ROWNUM ist wahrscheinlich die einfachste.
@carpenteri: Richtig, Analytics waren in 8i verfügbar - ich kann mich nicht an die Details erinnern, aber Analytics waren der Öffentlichkeit erst in 9i wirklich verfügbar.
OMG Ponys
Kleiner Kommentar - Vashs Antwort unten enthält ein ORDER BY für die innere Abfrage, was wichtig ist, wenn Sie den TOP-Wert von fname anstelle von 'first' möchten (was alles sein kann, höchstwahrscheinlich die erste eingefügte Zeile). Könnte eine Bearbeitung wert sein?
JulesLt
@JulesLt: Die vom OP bereitgestellte Abfrage enthält kein ORDER BY. Dies ist also eine Antwort, die eine exakte Übersetzung in die Oracle-Syntax darstellt.
OMG Ponys
Mein Missverständnis der SQL SERVER TOP-Syntax (fälschlicherweise angenommen, dass sie FIRST in RANK und nicht ROWNUM ähnelt). Abgestimmt.
JulesLt
3
Das Auswählen der ersten Zeile aus einer Tabelle und das Auswählen einer Zeile aus einer Tabelle sind zwei verschiedene Aufgaben und erfordern eine andere Abfrage. Es gibt viele Möglichkeiten, dies zu tun. Vier davon sind:
Zuerst
select max(Fname)from MyTbl;
Zweite
select min(Fname)from MyTbl;
Dritte
select Fname from MyTbl where rownum =1;
Vierte
select max(Fname)from MyTbl where rowid=(select max(rowid)from MyTbl)
Antworten:
Wenn Sie nur eine erste ausgewählte Zeile möchten, können Sie:
Sie können auch Analysefunktionen verwenden, um das oberste x zu bestellen und zu übernehmen:
quelle
quelle
top X
man ändern kann inWHERE ROWNUM <= X
Mit Oracle 12c (Juni 2013) können Sie es wie folgt verwenden.
quelle
OFFSET 0 ROWS
anscheinend nicht notwendig, Sie können verwendenFETCH NEXT 1 ROWS ONLY
oder sogarFETCH FIRST ROW ONLY
, die Reihenfolge nach ist wichtig oder es wird gleichbedeutend sein, nur a zu verwendenWHERE rownum = 1
. Ich habe es sogar in einer OUTER APPLY-Anweisung versucht und es hat dort wie die TOP-Funktion von Ms-SQL funktioniert.TIES
. Siehe dies für die Fälle , in denen Bindungen auftreten für Version12c +
und12c -
Sie können
ROW_NUMBER()
eineORDER BY
Klausel in der Unterabfrage verwenden und diese Spalte anstelle von verwendenTOP N
. Dies kann Schritt für Schritt erklärt werden.Siehe die folgende Tabelle mit zwei Spalten
NAME
undDT_CREATED
.Wenn Sie unabhängig davon nur die ersten beiden Daten verwenden müssen
NAME
, können Sie die folgende Abfrage verwenden. Die Logik wurde in die Abfrage geschriebenERGEBNIS
In einigen Situationen müssen wir die
TOP N
jeweiligen Ergebnisse auswählenNAME
. In diesem Fall können wirPARTITION BY
mit einerORDER BY
Klausel in der Unterabfrage verwenden. Beziehen Sie sich auf die folgende Abfrage.ERGEBNIS
quelle
with (select ... ) as
ändert CTE ( Klausel) nichts an diesem Problem. CTE zielt nur darauf ab, Abfragen zu lesen und zu unterstützen. Richtig? @ Sarath AvanavuSie können so etwas tun
Sie können auch die Analysefunktionen RANK und / oder DENSE_RANK verwenden , aber ROWNUM ist wahrscheinlich die einfachste.
quelle
quelle
Verwenden:
Wenn Sie Oracle9i + verwenden, können Sie Analysefunktionen wie ROW_NUMBER () verwenden, die jedoch nicht so gut wie ROWNUM funktionieren .
quelle
Das Auswählen der ersten Zeile aus einer Tabelle und das Auswählen einer Zeile aus einer Tabelle sind zwei verschiedene Aufgaben und erfordern eine andere Abfrage. Es gibt viele Möglichkeiten, dies zu tun. Vier davon sind:
Zuerst
Zweite
Dritte
Vierte
quelle
Ich hatte das gleiche Problem und kann es mit dieser Lösung beheben:
Sie können Ihr Ergebnis vorher bestellen, um den ersten Wert oben zu haben.
Viel Glück
quelle