简体   繁体   English

MySQL限制组的记录

[英]MySQL limit records for a group

I've read the examples, but cannot get it to work for my example. 我已经阅读了这些示例,但无法让它适用于我的示例。

I have a table 'player' with columns 'pid' and 'name' and a table 'card' with columns 'pid', 'points'. 我有一个表'玩家',列'pid'和'name'以及一个表'card',列'pid','points'。

There are multiple card records to a player record. 玩家记录有多个卡片记录。

How can I query the top 5 records per player? 如何查询每位玩家的前5名记录?

This query returns eveything I need, but doesn't limit to 5 records per name. 此查询返回我需要的内容,但不限制每个名称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

You can use variables to assign a rank to each user: 您可以使用变量为每个用户分配排名:

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;

See SQL Fiddle with Demo 请参阅SQL Fiddle with Demo

MySQL does not support the "analytic" type function necessary to return the specified resultset. MySQL不支持返回指定结果集所需的“分析”类型函数。 We can emulate the function by making use of MySQL "user variables". 我们可以通过使用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

Note that the resultset from this statement differs from your original statement, in that it returns an extra column "seq". 请注意,此语句的结果集与原始语句不同,因为它返回一个额外的列“seq”。 This column will return values of 1,2,3,etc. 此列将返回1,2,3等值。 indicating whether this was the "first", "second", "third", etc. row for a particular p.name. 指示这是否是特定p.name的“第一”,“第二”,“第三”等行。

The expression used to derive this is basically checking whether the value of p.name on the current row matches the value from the previous row. 用于派生此表达式的表达式基本上是检查当前行上的p.name值是否与前一行的值匹配。 If it matches, we add a 1; 如果匹配,我们添加1; if it doesn't match, then we reset to zero. 如果它不匹配,那么我们重置为零。

The query will actually generate a result set for all rows for each p.name; 该查询实际上将为每个p.name生成所有行的结果集; the HAVING clause will restrict the rows that are actually returned to the client. HAVING子句将限制实际返回给客户端的行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM