我有这个查询
SELECT
user_id,
played_level,
sum( time_taken ) AS time_take
FROM answer
WHERE completed =1
GROUP BY played_level, user_id
ORDER BY time_take
LIMIT 20
此查询显示占用最少时间的所有用户ID。
但是现在我想用最短的时间显示用户ID。
user_id played_level time_take
1 18 19
1 12 21
2 3 25
6 3 26
2 2 27
6 4 27
1 8 32
预期产出:
user_id played_level time_taken
1 18 19
2 3 25
6 3 26
答案 0 :(得分:3)
首先从表
中选择所有distict user_id $distinct_users = "SELECT DISTINCT user_id FROM answer where addeddate BETWEEN :currdate1 AND :currdate2 AND completed=1";
$distinct_users_data = $conn->prepare($distinct_users);
$distinct_users_data->execute(array(':currdate1'=>$prev_date,':currdate2'=>$currdate2));
$distinct_users_arr = $distinct_users_data->fetchAll();
现在找到此user_id的最短时间并将其存储在数组
中 foreach($distinct_users_arr as $distict_data)
{
$user_ids=$distict_data['user_id'];
$all_user_time = "SELECT user_id, played_level, sum( time_taken ) AS time_take FROM answer where addeddate BETWEEN :currdate1 AND :currdate2
AND completed=1 AND user_id=:user_id GROUP BY played_level, user_id ORDER BY time_take limit 1";
$all_user_time_data = $conn->prepare($all_user_time);
$all_user_time_data->execute(array(':currdate1'=>$prev_date,':currdate2'=>$currdate2,':user_id'=>$user_ids));
$all_user_time_arr = $all_user_time_data->fetchAll();
$all_count= $all_user_time_data->rowCount();
foreach($all_user_time_arr as $leading_user)
{
$new_user_id= $leading_user['user_id'];
$new_time= $leading_user['time_take'];
$leader_board[] = array(
'user_id'=>$new_user_id,
'time_taken'=>$new_time
);
}
}
最后按时间排序该数组顺序。我们得到最终结果
foreach ($leader_board as $key => $row)
{
$sorting[$key] = $row['time_taken'];
}
array_multisort($sorting, SORT_ASC, $leader_board);
答案 1 :(得分:2)
虽然您可以使用join
执行此操作,但这很复杂,因为您必须重复聚合。您也可以使用嵌套聚合执行此操作。困难的部分是获得最小值的played_level
。以下查询使用技巧来使用substring_index()
/ group_concat()
来获取该功能。这是没有limit
子句的查询 - 我不太确定你想要限制什么:
select user_id,
substring_index(group_concat(played_level order by time_take), ',', 1) as played_level,
min(time_take) as time_take
from (SELECT user_id, played_level, sum( time_taken ) AS time_take
FROM answer
WHERE completed =1
GROUP BY played_level, user_id
) a
group by user_id
ORDER BY time_take;
答案 2 :(得分:0)
至SELECT DISTINCT
SELECT
DISTINCT user_id,
played_level,
sum( time_taken ) AS time_take
FROM answer
WHERE completed =1
GROUP BY played_level
ORDER BY time_take
LIMIT 20
你也可以像这样使用GROUP BY
。
SELECT
user_id,
played_level,
sum( time_taken ) AS time_take
FROM answer
WHERE completed =1
GROUP BY user_id
ORDER BY time_take
LIMIT 20
答案 3 :(得分:0)
我相信你的意思是:你想要每个用户完成的最后一级:
SELECT
user_id,
max(played_level) current user_level,
sum(time_taken) AS time_take
FROM answer
WHERE completed =1
GROUP BY user_id
ORDER BY time_take
LIMIT 20
答案 4 :(得分:0)
在这种情况下,你需要使用子查询
select user_id, played_level, min( time_taken ) AS time_take from( SELECT user_id, max(played_level) played_level, sum( time_taken ) AS time_take FROM answer WHERE completed =1 GROUP BY user_id ORDER BY time_take LIMIT 20 ) a group by user_id
答案 5 :(得分:0)
你可以尝试一下吗?
SELECT x.*
FROM (
SELECT
user_id,
played_level,
SUM(time_taken) AS time_take
FROM answer
WHERE completed = 1
GROUP BY played_level, user_id
) x INNER JOIN (
SELECT played_level, user_id, MIN(time_take) AS mn
FROM (
SELECT
user_id,
played_level,
SUM(time_taken) AS time_take
FROM answer
WHERE completed = 1
GROUP BY played_level, user_id
) y
GROUP BY user_id, played_level
) z ON x.user_id = z.user_id
AND x.played_level = z.played_level AND x.time_take = z.mn
内联视图z
每个(user_id,playing_level)都有MIN(time_take)
,最后加入原始查询。
答案 6 :(得分:0)
您需要通过子查询使用JOIN:
SELECT user_id, played_level, time_taken
FROM answer
JOIN (
SELECT user_id AS t_user_id, MIN(time_taken) AS min_time_taken
FROM answer
GROUP BY user_id
) t
ON answer.user_id = t.t_user_id AND answer.time_taken = t.min_time_taken
WHERE completed = 1
ORDER BY time_take
LIMIT 20