Gibt es eine Möglichkeit, die tatsächliche Zeilennummer von einer Abfrage zu erhalten?
Ich möchte in der Lage sein, eine Tabelle namens league_girl nach einem Feld namens score zu bestellen. und geben Sie den Benutzernamen und die tatsächliche Zeilenposition dieses Benutzernamens zurück.
Ich möchte die Benutzer in eine Rangfolge bringen, damit ich feststellen kann, wo sich ein bestimmter Benutzer befindet. Joe ist Position 100 von 200, d.h.
User Score Row
Joe 100 1
Bob 50 2
Bill 10 3
Ich habe hier ein paar Lösungen gesehen, aber ich habe die meisten probiert und keine von ihnen liefert tatsächlich die Zeilennummer.
Ich habe das ausprobiert:
SELECT position, username, score
FROM (SELECT @row := @row + 1 AS position, username, score
FROM league_girl GROUP BY username ORDER BY score DESC)
Wie abgeleitet
... aber es scheint nicht die Zeilenposition zurückzugeben.
Irgendwelche Ideen?
Möglicherweise möchten Sie Folgendes versuchen:
SELECT l.position,
l.username,
l.score,
@curRow := @curRow + 1 AS row_number
FROM league_girl l
JOIN (SELECT @curRow := 0) r;
Der JOIN (SELECT @curRow := 0)
-Teil ermöglicht die Initialisierung der Variablen, ohne dass ein separater SET
-Befehl erforderlich ist.
Testfall:
CREATE TABLE league_girl (position int, username varchar(10), score int);
INSERT INTO league_girl VALUES (1, 'a', 10);
INSERT INTO league_girl VALUES (2, 'b', 25);
INSERT INTO league_girl VALUES (3, 'c', 75);
INSERT INTO league_girl VALUES (4, 'd', 25);
INSERT INTO league_girl VALUES (5, 'e', 55);
INSERT INTO league_girl VALUES (6, 'f', 80);
INSERT INTO league_girl VALUES (7, 'g', 15);
Testanfrage:
SELECT l.position,
l.username,
l.score,
@curRow := @curRow + 1 AS row_number
FROM league_girl l
JOIN (SELECT @curRow := 0) r
WHERE l.score > 50;
Ergebnis:
+----------+----------+-------+------------+
| position | username | score | row_number |
+----------+----------+-------+------------+
| 3 | c | 75 | 1 |
| 5 | e | 55 | 2 |
| 6 | f | 80 | 3 |
+----------+----------+-------+------------+
3 rows in set (0.00 sec)
SELECT @i:[email protected]+1 AS iterator, t.*
FROM tablename t,(SELECT @i:=0) foo
Hier ist die Struktur der Vorlage, die ich verwendet habe:
select
/*this is a row number counter*/
( select @rownum := @rownum + 1 from ( select @rownum := 0 ) d2 )
as rownumber,
d3.*
from
( select d1.* from table_name d1 ) d3
Und hier ist mein Arbeitscode:
select
( select @rownum := @rownum + 1 from ( select @rownum := 0 ) d2 )
as rownumber,
d3.*
from
( select year( d1.date ), month( d1.date ), count( d1.id )
from maindatabase d1
where ( ( d1.date >= '2013-01-01' ) and ( d1.date <= '2014-12-31' ) )
group by YEAR( d1.date ), MONTH( d1.date ) ) d3
Sie können auch verwenden
SELECT @curRow := ifnull(@curRow,0) + 1 Row, ...
um die Zählervariable zu initialisieren.
Wenn Sie nur die Position eines bestimmten Benutzers nach der Reihenfolge anhand der Feldbewertung erfahren möchten, können Sie einfach alle Zeilen aus Ihrer Tabelle auswählen, deren Feldbewertung über der aktuellen Benutzerbewertung liegt. Verwenden Sie die zurückgegebene Zeilennummer + 1, um die Position dieses aktuellen Benutzers zu ermitteln.
Wenn Sie davon ausgehen, dass Ihr Tisch "league_girl" ist und Ihr Hauptfeld "id" ist, können Sie Folgendes verwenden:
SELECT count(id) + 1 as rank from league_girl where score > <your_user_score>
Wenn MySQL dies unterstützt, können Sie dies leicht mit einer Standard-SQL-Unterabfrage tun:
select
(count(*) from league_girl l1 where l2.score > l1.score and l1.id <> l2.id) as position,
username,
score
from league_girl l2
order by score;
Bei großen Mengen angezeigter Ergebnisse ist dies etwas zu langsam und Sie möchten stattdessen zu einem Self Join wechseln.
Ich weiß, dass das OP nach einer mysql
-Antwort fragt, aber da ich die anderen Antworten gefunden habe, die für mich nicht funktionieren,
order by
Um Zeit für andere wie mich zu sparen, indizieren Sie die Zeile einfach nach dem Abrufen aus der Datenbank
beispiel in PHP:
$users = UserRepository::loadAllUsersAndSortByScore();
foreach($users as $index=>&$user){
$user['rank'] = $index+1;
}
beispiel in PHP mit Offset und Limit für Paging:
$limit = 20; //page size
$offset = 3; //page number
$users = UserRepository::loadAllUsersAndSortByScore();
foreach($users as $index=>&$user){
$user['rank'] = $index+1+($limit*($offset-1));
}
Ich fand die ursprüngliche Antwort unglaublich hilfreich, wollte aber auch eine bestimmte Anzahl von Zeilen anhand der von mir eingefügten Zeilennummern verwenden. Daher verpackte ich die gesamte ursprüngliche Antwort in einer Unterabfrage, sodass ich auf die Zeilennummer verweisen konnte, die ich eingefügt habe.
SELECT * FROM
(
SELECT *, @curRow := @curRow + 1 AS "row_number"
FROM db.tableName, (SELECT @curRow := 0) r
) as temp
WHERE temp.row_number BETWEEN 1 and 10;
Eine Unterabfrage in einer Unterabfrage ist nicht sehr effizient. Es lohnt sich also zu testen, ob Sie ein besseres Ergebnis erzielen, wenn Ihr SQL-Server diese Abfrage verarbeitet, oder ob Sie die gesamte Tabelle abrufen und die Zeilen die Anwendung/den Web-Server nachträglich bearbeiten lassen .
Persönlich ist mein SQL-Server nicht überlastet, daher wäre es besser, die verschachtelten Unterabfragen zu bearbeiten.