我得到了下面这个SQL问题的帮助,总结了每个团队的前5名长度。对我来说现在的问题似乎是SQL随机选择数据库中的5个例如7行,而不是前5个。任何人对我有什么想法?会非常感兴趣的!
select team, sum(length) as totalScore
from
(
SELECT
t.*,
@num_in_group:=case when @team!=team then @num_in_group:=0 else @num_in_group:=@num_in_group+1 end as num_in_group,
@team:=team as t
FROM reg_catches t, (select @team:=-1, @num_in_group:=0) init
ORDER BY team asc
) sub
WHERE
sub.num_in_group <= 4 and
competition = 16 and
team = 25
GROUP BY team
ORDER BY totalScore DESC;
表
team length competition
----------------------
26 70 16
25 70 16
25 95 16
25 98 16
25 100 16
25 100 16
25 100 16
25 122 16
通缉输出:
team totalScore
---- -----------
25 520
26 70
祝你好运, 基督教
答案 0 :(得分:1)
在内部查询中添加另一个排序子句
ORDER BY team asc ,length desc
这将首先按团队排序表格行,然后为每个团队按行长度列值排序,因此团队的更高价值将首先返回
或者在不使用变量的情况下获得相同结果的另一种方法
select a.team, sum(a.length) as totalScore
from (
select b.*,(
select count(*)
from reg_catches c
where b.team = c.team
and b.length < c.length
) + 1 rownum
from reg_catches b
) a
where a.rownum <=5
group by a.team
order by totalScore DESC;
确保在团队和长度列上有一个索引以获得更好的性能
答案 1 :(得分:1)
除了您当前查询的任何逻辑问题外,MySQL会话变量的行为可能还有其他风险。 MySQL不保证在select语句中对会话变量进行赋值的顺序。因此,使用分区(您的问题)模拟排名的查询可能不可靠。但我们仍然可以通过使用相关子查询来标记每个团队的前5个长度来解决问题:
SELECT
team,
SUM(length) AS totalScore
FROM
(
SELECT
team,
length,
competition,
(SELECT COUNT(*) FROM reg_catches t2
WHERE t2.team = t1.team AND t2.length >= t1.length) cnt
FROM reg_catches t1
) t
WHERE
cnt <= 5 AND
competition = 16
GROUP BY
team
ORDER BY
team;
请注意,如果存在关联,此查询有限制。如果你期望有关系,那么我们可以通过使用其他一些栏来解决这个问题。
<强>输出:强>
team totalScore
1 25 520
2 26 70
在这里演示:
答案 2 :(得分:1)
如果您想获得每个team
的前5行,您可以使用参数来对每个团队的结果进行排名:
SELECT *,
(@rank := if(@team = team, @rank + 1, if(@team := team, 1, 1))) as rank
FROM (SELECT * from reg_catches order by team, length desc) ordered
HAVING rank <= 5
ORDER BY team, rank asc
哪会产生以下结果:http://sqlfiddle.com/#!9/6042ae/1
| team | length | competition | rank |
+------+--------+-------------+------+
| 25 | 99 | 16 | 1 |
| 25 | 98 | 16 | 2 |
| 25 | 77 | 16 | 3 |
| 25 | 76 | 16 | 4 |
| 25 | 73 | 16 | 5 |
| 26 | 96 | 16 | 1 |
| 26 | 88 | 16 | 2 |
| 26 | 87 | 16 | 3 |
| 26 | 83 | 16 | 4 |
| 26 | 79 | 16 | 5 |
然后,如果需要,您可以将该查询包装在一个简单的聚合/组中,以获得每个团队前5名的总数
SELECT team, sum(length) as 'total score' FROM
(SELECT *,
(@rank := if(@team = team, @rank + 1, if(@team := team, 1, 1))) as rank
FROM (SELECT * from reg_catches order by team, length desc) ordered
HAVING rank <= 5
ORDER BY team, rank asc) top5
GROUP BY team
根据http://sqlfiddle.com/#!9/6042ae/2
| team |total score|
+-------+-----------+
| 25 | 423 |
| 26 | 433 |
| 27 | 426 |
通常的警告将适用于参数,但如果没有它们,您无法在MySQL中真正“排名”。我还发现这对于在应用参数之前以正确的顺序获得分数非常敏感。
虽然这可能不是最优秀的解决方案,但我希望它有所帮助