2009-05-26 7 views
2

Die folgende Abfrage ist perfekt funktional und fragt eine einzelne Tabelle ab, um die letzten 50 Benutzernamen zu finden, die über eine fortlaufende userid-Nummernspalte hinzugefügt wurden.Eleganter SQL?

Logik so weit ist: herauszufinden, die höchste Benutzer-ID; subtrahiere 50 davon; Nutzernamen zurück holen, wo größer.

Aber es sieht nicht elegant, und verwendet zwei Unterabfragen ist es Ziel zu erreichen:

SELECT username 
FROM table 
WHERE userid IN 
    (SELECT userid 
    FROM table 
    WHERE userid > 
    (SELECT MAX(userid) -50 
    FROM table)) 

Gibt es eine Möglichkeit, dies weniger verschachtelte zu machen? Effizienter? Eleganter? Jede Hilfe wird sehr geschätzt, da dies nicht der beste Weg sein kann!

Prost & vielen Dank
Ali

+0

Ich kenne SQL, aber ich bin mir nicht sicher über die Oracle-Variante.Haben Sie sich die TOP-Erklärung angesehen? In MS SQL (es sollte das gleiche) können Sie tun; Top 50 Benutzernamen aus der Tabelle auswählen Order By UserId Desc; –

Antwort

6

Die bereitgestellten Antworten in die richtige Richtung sind. Sie können ROWNUM verwenden, um TOP-N-Stil-Ergebnisse auszuwählen.

Bitte seien Sie vorsichtig und beachten Sie, dass das rownum den Abfrageergebnissen nach der Prädikation, aber vor dem ORDER BY zugewiesen wird. Probieren Sie etwas wie folgt aus:

SELECT username 
FROM 
    (SELECT username 
    FROM table 
    ORDER BY userid DESC) 
WHERE rownum <= 50 
+0

Im Anschluss an meine Antwort, sollten Sie diese sehr nützlich finden: http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html –

+0

Vielen Dank für eine gute Antwort und den Link, ChrisCM . Das funktioniert gut. –

0

Hängt Sie auf der Datenbank verwenden, aber so etwas wie dies versuchen:

Orakel: wählen Benutzernamen aus der Tabelle von Benutzer-ID, wo rownum < 50 um;

postgresql: Benutzernamen aus Tabelle auswählen Reihenfolge nach Benutzer-ID Limit 10;

+0

rownum index beginnt bei 1 und nicht bei 0, also brauchst du ein kleiner als gleich, um 50 Zeilen zu erhalten. das gibt nur 49 zurück. –

+1

Ihre Oracle-Lösung funktioniert nicht, weil Oracle zuerst das Wownown <50 ausführt, erst danach wird die Order durch ausgeführt. Siehe auch Eoin Campbell. – tuinstoel

1

Rein für die Ästhetik verwende ich SQLinForm das ist ein Java-Applet, das Ihre SQL sehr schön formatiert. Es ist flexibel mit vielen Optionen auch.

+0

Für wen auch immer das stimmte, er fragte nach Eleganz und ich habe darauf hingewiesen, das war rein für die Ästhetik; eleganter Code sollte sowohl im Format als auch im Code lesbar sein ... – joshcomley

0

wie etwa:

SELECT username FROM table ORDER BY userid DESC LIMIT 50 
+0

Es wird einen Grund für die Unterabfragen geben. –

+1

Das ist MySql. –

+0

Der Grund für die Unterabfrage ist, dass sie die letzten 50 Benutzer abholen kann und nicht Benutzer mit einer Benutzer-ID> 50. ie userid> max (userid) -50 –

0

Wenn Sie ein Feld Datecreated in der Benutzertabelle haben würden Sie die Abfrage wie folgt machen könnte:

SELECT TOP 50 username 
FROM table 
ORDER BY DateCreated DESC 
+1

Das ist die SQL Server-Syntax –

+0

Es tut mir leid, habe das Orakel-Tag nicht gesehen ... gibt es kein Orakel gleichwertig für die "TOP x" -Klausel? – fretje

+0

Oracle verwendet "WHERE RowNum <= X"; RowNum ist eine spezielle Oracle-Spalte – Andomar

2
SELECT * FROM (SELECT UserName FROM Table ORDER BY UserID DESC) 
WHERE RowNum <= 50 

... denke ich. .. war schon eine Weile her, seit ich mit Oracle herumhantierte.

Dies ist in etwa die gleiche wie

SELECT Top 50 in SQLServer

und

SELECT ... LIMIT 50 in MySql

+0

@HankGay schöner Ort. Prost –

2

können Sie verwenden ROW_NUMBER() eine Nummer zu jeder Zeile zuweisen, basierend auf seiner Position in einer geordneten Liste. Zum Beispiel, nummerieren Reihen mit 1 für die höchste userid Start:

SELECT username 
FROM (
    SELECT 
     ROW_NUMBER() OVER (ORDER BY user_id DESC) AS RowNr, 
     * 
    FROM users 
) sub 
WHERE RowNr < 50 

Anders als bei der Abfrage in der Frage, dies funktionieren wird, wenn Benutzer-ID nicht aufeinander folgend ist.

Verwandte Themen