1

例を読みましたが、私の例では機能しません。

'pid'と'name'の列を持つテーブル'player'と、'pid'、'points'の列を持つテーブル'card'があります。

プレーヤーレコードには複数のカードレコードがあります。

プレーヤーごとに上位5つのレコードをクエリするにはどうすればよいですか?

このクエリは必要なものをすべて返しますが、名前ごとに5レコードに制限されていません。

SELECT p.pid, p.name, c.points as lp
FROM player as p, card as c
WHERE p.pid=c.pid
ORDER BY p.name,  lp DESC
4

2 に答える 2

2

変数を使用して、各ユーザーにランクを割り当てることができます。

select pid, name, lp
from
(
    SELECT pid, 
        name, 
        points as lp,
        @prev := @curr,
        @curr := name,
        @rank := IF(@prev = @curr, @rank+1, 1) AS rank
    FROM
    (
      select p.pid, name, points
      FROM player as p
      INNER JOIN card as c
          ON p.pid=c.pid
    ) src, (SELECT @curr := null, @prev := null, @rank := 1) r
    ORDER BY name, points desc
) src
where rank <= 5
order by name, lp DESC;

SQL FiddlewithDemoを参照してください

于 2013-01-14T22:14:04.830 に答える
1

MySQLは、指定された結果セットを返すために必要な「分析」タイプの関数をサポートしていません。MySQLの「ユーザー変数」を利用して関数をエミュレートできます。

SELECT IF(@prev_name = p.name,@n:=@n+1,@n:=1) AS seq
     , @prev_name := p.name AS name
     , c.points as lp
  FROM player as p
  JOIN card as c
    ON c.pid = p.pid
  JOIN (SELECT @n := 0, @prev_name := NULL) i
 HAVING seq <= 5
 ORDER BY p.name, lp DESC

このステートメントの結果セットは、追加の列「seq」を返すという点で、元のステートメントとは異なることに注意してください。この列は、1、2、3などの値を返します。これが特定のp.nameの「最初の」、「2番目の」、「3番目の」などの行であったかどうかを示します。

これを導出するために使用される式は、基本的に、現在の行のp.nameの値が前の行の値と一致するかどうかをチェックすることです。一致する場合は、1を追加します。一致しない場合は、ゼロにリセットします。

クエリは実際には、各p.nameのすべての行の結果セットを生成します。このHAVING句は、実際にクライアントに返される行を制限します。

于 2013-01-14T22:27:15.157 に答える