クエリから実際の行番号を取得する方法はありますか?
スコアと呼ばれるフィールドで、league_girlというテーブルを注文できるようにしたいと思います。ユーザー名とそのユーザー名の実際の行位置を返します。
ユーザーをランク付けして、特定のユーザーがどこにいるかを確認できるようにします。ジョーは200のうち100位、つまり.
User Score Row
Joe 100 1
Bob 50 2
Bill 10 3
ここでいくつかの解決策を見ましたが、それらのほとんどを試しましたが、実際には行番号を返しません。
私はこれを試しました:
SELECT position, username, score
FROM (SELECT @row := @row + 1 AS position, username, score
FROM league_girl GROUP BY username ORDER BY score DESC)
派生した
...しかし、行の位置を返すようには見えません。
何か案は?
次のことを試してください。
SELECT l.position,
l.username,
l.score,
@curRow := @curRow + 1 AS row_number
FROM league_girl l
JOIN (SELECT @curRow := 0) r;
JOIN (SELECT @curRow := 0)
部分を使用すると、別個のSET
コマンドを必要とせずに変数を初期化できます。
テストケース:
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);
テストクエリ:
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;
結果:
+----------+----------+-------+------------+
| 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:=@i+1 AS iterator, t.*
FROM tablename t,(SELECT @i:=0) foo
ここに私が使用したテンプレートの構造があります:
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
そして、ここに私の作業コードがあります:
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
使用することもできます
SELECT @curRow := ifnull(@curRow,0) + 1 Row, ...
カウンター変数を初期化します。
フィールドスコア順で特定のユーザーの位置を知りたいだけの場合は、フィールドスコアが現在のユーザースコアより高いテーブルからすべての行を選択するだけです。そして、返された行番号+ 1を使用して、この現在のユーザーの位置を確認します。
テーブルが「league_girl」で、プライマリフィールドが「id」であると仮定すると、これを使用できます。
SELECT count(id) + 1 as rank from league_girl where score > <your_user_score>
MySQLがサポートしていると仮定すると、標準のSQLサブクエリを使用して簡単にこれを行うことができます。
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;
大量の結果が表示される場合、これは少し遅くなり、代わりに自己結合に切り替えます。
OPがmysql
の回答を求めていることは知っていますが、他の回答が役に立たないことがわかったため、
order by
で失敗します私のような他の人の時間を節約するために、データベースからそれらを取得した後に行にインデックスを付けるだけ
pHPの例:
$users = UserRepository::loadAllUsersAndSortByScore();
foreach($users as $index=>&$user){
$user['rank'] = $index+1;
}
PHPの例では、ページングにオフセットと制限を使用しています。
$limit = 20; //page size
$offset = 3; //page number
$users = UserRepository::loadAllUsersAndSortByScore();
foreach($users as $index=>&$user){
$user['rank'] = $index+1+($limit*($offset-1));
}
元の答えは信じられないほど役に立ちましたが、挿入した行番号に基づいて特定の行セットを取得したかったのです。そのため、挿入した行番号を参照できるように、元の回答全体をサブクエリでラップしました。
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;
サブクエリにサブクエリを含めることはあまり効率的ではないため、SQLサーバーにこのクエリを処理させるか、テーブル全体をフェッチしてアプリケーション/ Webサーバーに事後の行を操作させることで、より良い結果が得られるかどうかをテストする価値があります。
個人的に、私のSQLサーバーは過度にビジーではないので、ネストされたサブクエリを処理することが望ましいです。