web-dev-qa-db-ja.com

MySQLを使用して、テーブル内のレコードインデックスを含む列を生成するにはどうすればよいですか?

クエリから実際の行番号を取得する方法はありますか?

スコアと呼ばれるフィールドで、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) 

派生した

...しかし、行の位置を返すようには見えません。

何か案は?

99
TheBounder

次のことを試してください。

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)
168
Daniel Vassallo
SELECT @i:=@i+1 AS iterator, t.*
FROM tablename t,(SELECT @i:=0) foo
37
Peter Johnson

ここに私が使用したテンプレートの構造があります:

  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
7
goadreamer

使用することもできます

SELECT @curRow := ifnull(@curRow,0) + 1 Row, ...

カウンター変数を初期化します。

4
Hearth

フィールドスコア順で特定のユーザーの位置を知りたいだけの場合は、フィールドスコアが現在のユーザースコアより高いテーブルからすべての行を選択するだけです。そして、返された行番号+ 1を使用して、この現在のユーザーの位置を確認します。

テーブルが「league_girl」で、プライマリフィールドが「id」であると仮定すると、これを使用できます。

SELECT count(id) + 1 as rank from league_girl where score > <your_user_score>
3
Heryno

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;

大量の結果が表示される場合、これは少し遅くなり、代わりに自己結合に切り替えます。

3
ftzdomino

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));
        }
0
azerafati

元の答えは信じられないほど役に立ちましたが、挿入した行番号に基づいて特定の行セットを取得したかったのです。そのため、挿入した行番号を参照できるように、元の回答全体をサブクエリでラップしました。

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サーバーは過度にビジーではないので、ネストされたサブクエリを処理することが望ましいです。

0
BasicExp