【问题标题】:How to find rank based on two values in php?如何根据php中的两个值查找排名?
【发布时间】:2020-04-19 23:16:36
【问题描述】:

我在 php 中有一个与锻炼相关的 Web 应用程序,其中包含锻炼表,该表根据活动类型(如跑步、游泳、骑自行车等)存储用户的日常锻炼数据。我需要根据高排名系统生成排行榜。

Default workout table

SELECT 
  SUM(avg_speed) AS average_speed, 
  SUM(max_speed) AS maximum_speed, 
  date_created, 
  user_id 
FROM workouts 
WHERE date_created LIKE '%2019-12%' 
GROUP BY user_id

通过这个查询,我得到如下输出:

output after running select query

我需要的输出应该基于average_speed

【问题讨论】:

  • 1) 您从所有可能的user_id 中随机获得date_created。 2) 要求的输出应该基于average_speed使用HAVING
  • 是的,因为对于特定月份我需要获取数据
  • 你必须得到一个具体的日期。例如,MIN(date_created).
  • 考虑到我的 date_created 是 2019-12,所以我只需要根据最小和最大速度生成 12 月份的排名

标签: php mysql


【解决方案1】:

尝试像这样玩查询。

select user_id,avg,max from users nu
join
(
    select sum(avg_speed) as avg,sum(max_speed) as max,user_id FROM workouts group by user_id
)t2 on t2.user_id=nu.id 
 where avg<30 and max <50
 and date_created LIKE '%2019-12%'
group by t2.user_id order by avg desc;

在您的 php 代码中循环此结果以添加您的排名逻辑,如下例所示。 (以下逻辑和代码未经测试)。

$rank=0;
$same_rank=0;
foreach($workouts as $key=>$item)
{
 $avg=$item->avg;
 if($avg!=$prev_item)
 { 
    $add_rank=$same_rank!=0?$same_rank:1;
    $rank=$rank+$add_rank;
    $same_rank=0;
 }
 else
 {
  $same_rank++; //increments if same value repeated
 }

 $workouts[$key]['rank']=$rank;
 $prev_item=$avg;


 }
echo $workouts;

这可能对你有帮助

【讨论】:

    【解决方案2】:

    你可以试试这个 SQL 语句:

    SELECT s1.avg_speed, s1.max_speed, s1.user_id,
           @row_num:=IF(s1.avg_speed = @last_avg_speed, @row_num, @origin_row_num+1) rank_no,
           @last_avg_speed:=s1.avg_speed last_avg_speed,
           @origin_row_num:=@origin_row_num+1 origin_row_num
    FROM (
        SELECT SUM(avg_speed) avg_speed, SUM(max_speed) max_speed, user_id FROM workouts
            WHERE date_created LIKE '2019-12%'
            GROUP BY user_id
    ) s1, (SELECT @origin_row_num:=0, @row_num:=0, @last_avg_speed:=0) R
    WHERE s1.avg_speed < 30 AND s1.max_speed < 50
    ORDER BY s1.avg_speed DESC
    

    这是我的测试代码:

    create table workouts
    (
        id int auto_increment
            primary key,
        user_id int not null,
        date_created date null,
        activity_type varchar(10) null,
        avg_speed float null,
        max_speed float null
    );
    DELETE FROM workouts WHERE user_id IN (1, 2, 3)
    INSERT INTO workouts (id, user_id, date_created, activity_type, avg_speed, max_speed)
    VALUES (NULL, 1, '2019-12-01', 'Walk', 1, 10),
           (NULL, 1, '2019-12-02', 'Walk', 1, 10),
           (NULL, 1, '2019-12-03', 'Walk', 1, 10),
           (NULL, 1, '2019-12-04', 'Walk', 1, 10),
    
           (NULL, 2, '2019-12-01', 'Walk', 1, 10),
           (NULL, 2, '2019-12-02', 'Walk', 5, 10),
           (NULL, 2, '2019-12-03', 'Walk', 1, 10),
           (NULL, 2, '2019-12-04', 'Walk', 1, 10),
    
           (NULL, 3, '2019-12-01', 'Walk', 1, 10),
           (NULL, 3, '2019-12-02', 'Walk', 5, 10),
           (NULL, 3, '2019-12-03', 'Walk', 1, 10),
           (NULL, 3, '2019-12-04', 'Walk', 1, 10);
    
    SELECT s1.avg_speed, s1.max_speed, s1.user_id,
           @row_num:=IF(s1.avg_speed = @last_avg_speed, @row_num, @origin_row_num+1) rank_no,
           @last_avg_speed:=s1.avg_speed last_avg_speed,
           @origin_row_num:=@origin_row_num+1 origin_row_num
    FROM (
        SELECT SUM(avg_speed) avg_speed, SUM(max_speed) max_speed, user_id FROM workouts
            WHERE date_created LIKE '2019-12%'
            GROUP BY user_id
    ) s1, (SELECT @origin_row_num:=0, @row_num:=0, @last_avg_speed:=0) R
    WHERE s1.avg_speed < 30 AND s1.max_speed < 50
    ORDER BY s1.avg_speed DESC
    
    

    输出:

    |--------------------------------------------------|
    |avg_speed|max_speed|user_id|rank_no|last_avg_speed|
    |--------------------------------------------------|
    |8        |40       |2      |1      |8             |
    |--------------------------------------------------|
    |8        |40       |3      |1      |8             |
    |--------------------------------------------------|
    |4        |40       |1      |3      |4             |
    |--------------------------------------------------|
    

    在最后一列last_avg_speed总是等于avg_speed,你可以忽略它。

    顺便说一句,如果你使用的是 MySQL 8.0.0 或更高版本,你可以使用ROW_NUMBER()RANK() 函数来解决它,非常非常简单。 here 是文档。

    【讨论】:

    • 谢谢...此代码符合我的要求。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-11
    • 2019-01-05
    • 2021-06-20
    • 1970-01-01
    • 2014-11-09
    • 2015-03-24
    • 1970-01-01
    相关资源
    最近更新 更多