从 table 中获取用户的最高分
Get user's highest score from a table
我觉得这是一个非常简单的问题,但也许我现在脑子放屁,似乎不知道该怎么做。
我有一个 MySQL table 结构,如下所示
+---------------------------------------------------+
| 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
这应该 return ID = 3 的行。现在我想要的是一个查询 运行 能够 return 每个唯一的 1 这样的行 user_id 在 table 中。所以最终的结果会是这样的
+---------------------------------------------------+
| id | date | score | speed | user_id |
+---------------------------------------------------+
| 3 | 2016-11-17 | 6 | 21852 | 17 |
| 6 | 2016-11-17 | 8 | 49434 | 61 |
此外,我能否在同一个查询中提出另一个问题,根据相同的排序标准(得分降序、速度升序)进一步对最终结果 table 进行排序。谢谢
对于mysql
您可以尝试在子选择中使用双选并按
分组
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
);
很容易使用变量来模拟row_number() over (partition by Order by)
解释:
- 首先在子查询中创建两个变量。
- 按
user_id
排序,因此当用户更改 @rn
时重置为 1
- 按
score
降序排列,speed
升序排列,这样每一行都会有一个 row_number,而你想要的总是会有 rn = 1
@rn :=
你为每一行改变 @rn
- 如果您有新的
user_id
,则 @rn
设置为 1
- 否则
@rn
设置为@rn+1
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
输出
使用相关子查询的简单方法:
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)
上的索引。
我觉得这是一个非常简单的问题,但也许我现在脑子放屁,似乎不知道该怎么做。
我有一个 MySQL table 结构,如下所示
+---------------------------------------------------+
| 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
这应该 return ID = 3 的行。现在我想要的是一个查询 运行 能够 return 每个唯一的 1 这样的行 user_id 在 table 中。所以最终的结果会是这样的
+---------------------------------------------------+
| id | date | score | speed | user_id |
+---------------------------------------------------+
| 3 | 2016-11-17 | 6 | 21852 | 17 |
| 6 | 2016-11-17 | 8 | 49434 | 61 |
此外,我能否在同一个查询中提出另一个问题,根据相同的排序标准(得分降序、速度升序)进一步对最终结果 table 进行排序。谢谢
对于mysql
您可以尝试在子选择中使用双选并按
分组 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
);
很容易使用变量来模拟row_number() over (partition by Order by)
解释:
- 首先在子查询中创建两个变量。
- 按
user_id
排序,因此当用户更改@rn
时重置为 1 - 按
score
降序排列,speed
升序排列,这样每一行都会有一个 row_number,而你想要的总是会有rn = 1
@rn :=
你为每一行改变@rn
- 如果您有新的
user_id
,则@rn
设置为 1 - 否则
@rn
设置为@rn+1
- 如果您有新的
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
输出
使用相关子查询的简单方法:
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)
上的索引。