我有一种感觉这是一个非常简单的问题,但也许我现在正在做脑屁并且似乎无法弄清楚如何去做。
我有一个类似于下面的MySQL表结构
+---------------------------------------------------+
| id | date | score | speed | user_id |
+---------------------------------------------------+
| 1 | 2016-11-17 | 2 | 133291 | 17 |
| 2 | 2016-11-17 | 6 | 82247 | 17 |
| 3 | 2016-11-17 | 6 | 21852 | 17 |
| 4 | 2016-11-17 | 1 | 109338 | 17 |
| 5 | 2016-11-17 | 7 | 64762 | 61 |
| 6 | 2016-11-17 | 8 | 49434 | 61 |
现在我可以通过这样做获得特定用户的最佳表现
SELECT *
FROM performance
WHERE user_id = 17 AND date = '2016-11-17'
ORDER BY score desc,speed asc LIMIT 1
这应该返回ID = 3的行。现在我想要的是运行一个查询,以便能够为表中的每个唯一user_id返回1个这样的行。因此得到的结果将是这样的
+---------------------------------------------------+
| id | date | score | speed | user_id |
+---------------------------------------------------+
| 3 | 2016-11-17 | 6 | 21852 | 17 |
| 6 | 2016-11-17 | 8 | 49434 | 61 |
此外,我是否可以在同一查询中有另一个问题,该问题将通过相同的排序条件(得分desc,速度asc)进一步对此最终结果表进行排序。感谢
答案 0 :(得分:3)
一种简单的方法使用相关子查询:
select p.*
from performance p
where p.date = '2016-11-17' and
p.id = (select p2.id
from performance p2
where p2.user_id = p.user_id and p2.date = p.date
order by score desc, speed asc
limit 1
);
这应该能够利用performance(date, user_id, score, speed)
上的索引。
答案 1 :(得分:2)
使用变量轻松模拟row_number() over (partition by Order by)
说明:
user_id
排序,以便用户将@rn
重置更改为1 score
desc,speed
asc排序,以便每一行都有一个row_number,而您想要的那一行将有rn = 1
@rn :=
您为每行更改@rn
user_id
,则@rn
设置为1 @rn
设置为@rn+1
<强> SQL Fiddle Demo 强>
SELECT `id`, `date`, `score`, `speed`, `user_id`
FROM (
SELECT *,
@rn := if(@user_id = `user_id`,
@rn + 1 ,
if(@user_id := `user_id`,1,1)
) as rn
FROM Table1
CROSS JOIN (SELECT @user_id := 0, @rn := 0) as param
WHERE date = '2016-11-17'
ORDER BY `user_id`, `score` desc, `speed` asc
) T
where T.rn =1
<强>输出强>
答案 2 :(得分:0)
对于mysql
您可以尝试使用subselect中的double和
分组 select * from performance
where (user_id, score,speed ) in (
SELECT user_id, max_score, max(speed)
FROM performance
WHERE (user_id, score) in (select user_id, max(score) max_score
from performance
group by user_id)
group by user_id, max_score
);