【问题标题】:Most recent date with maximum score得分最高的最近日期
【发布时间】:2017-08-14 08:01:43
【问题描述】:

我有下面的表定义。

CREATE TABLE IF NOT EXISTS ranking (  
    user_id int(11) unsigned NOT NULL, 
    create_date date NOT NULL,  
    score double(8,2),
    PRIMARY KEY (user_id, create_date)
)

insert into ranking (user_id, create_date, score) values  
    (1, '2017-03-01', 100),  
    (1, '2017-03-02',  90),  
    (1, '2017-03-03',  80),  
    (1, '2017-03-04', 100), 
    (1, '2017-03-05',  90),  
    (2, '2017-03-01',  90),  
    (2, '2017-03-02',  80),  
    (2, '2017-03-03', 100),  
    (2, '2017-03-5', 100),  
    (3, '2017-03-01',  80),  
    (3, '2017-03-02', 100),  
    (3, '2017-03-03',  90),  
    (3, '2017-03-6', 100);

select * from ranking;  
    user_id | create_date | score   
          1 | 2017-03-01  |   100  
          1 | 2017-03-02  |    90   
          1 | 2017-03-03  |    80  
          1 | 2017-03-04  |   100   
          1 | 2017-03-05  |    90  
          2 | 2017-03-01  |    90   
          2 | 2017-03-02  |    80   
          2 | 2017-03-03  |   100   
          2 | 2017-03-05  |   100   
          3 | 2017-03-01  |    80   
          3 | 2017-03-02  |   100   
          3 | 2017-03-03  |    90   
          3 | 2017-03-06  |   100  

我想要的是对于每个user_id,获取得分最高的最近create_date。比如上面的例子,对于user_id = 1,当create_date = 2017-03-01 and create_date = 2017-03-04时,最高分是100,但我只想要最高分的最近日期,即,create_date = 2017-03-04,score = 100。查询结果如下:

user_id | create_date | score   
      1 | 2017-03-04  |   100   
      2 | 2017-03-05  |   100  
      3 | 2017-03-06  |   100  

以下是我的解决方案,它返回了预期的结果,但我相信存在更好的解决方案。

SELECT a.* from   
(  
    SELECT s1.user_id , s1.create_date, s1.score FROM ranking AS s1   
    INNER JOIN  
    (SELECT user_id , FORMAT(max(score), 0) as best_score FROM ranking GROUP BY user_id ) AS s2  
    ON s1.user_id = s2.user_id AND s1.score = s2.best_score  
) a   
NATURAL LEFT JOIN   
(  
    SELECT s1.user_id , s1.create_date, s1.score FROM ranking AS s1   
    INNER JOIN   
    (  
        SELECT user_id , create_date, score FROM ranking  
    ) s2  
    WHERE s1.user_id = s2.user_id AND s1.score = s2.score AND s1.create_date < s2.create_date  
) b  
WHERE b.user_id IS NULL;  

谁能提供更好的解决方案?谢谢。

【问题讨论】:

    标签: mysql


    【解决方案1】:

    试试这个查询 -

    SELECT r1.* FROM ranking r1
      JOIN (SELECT user_id, MAX(score) max_score FROM ranking GROUP BY user_id) r2
        ON r1.user_id = r2.user_id AND r1.score = r2.max_score
      JOIN (SELECT user_id, score, MAX(create_date) max_create_date FROM ranking GROUP BY user_id, score) r3
        ON r1.user_id = r3.user_id AND r1.score = r3.score AND r1.create_date = r3.max_create_date;
    

    1   04-Mar-17   100
    2   05-Mar-17   100
    3   06-Mar-17   100
    

    【讨论】:

      【解决方案2】:
      SELECT t1.user_id,
             MAX(t1.create_date) AS max_date,
             t2.max_score
      FROM ranking t1
      INNER JOIN
      (
          SELECT user_id, MAX(score) AS max_score
          FROM ranking
          GROUP BY user_id
      ) t2
          ON t1.user_id = t2.user_id AND
             t1.score   = t2.max_score
      GROUP BY t1.user_id
      

      输出:

      演示在这里:

      Rextester

      【讨论】:

      • 你也得到了很好的答案。你知道我有时从你编码的方式中学到了什么。@tim 你我的导师。
      【解决方案3】:

      试试这个:

      select user_id, max(create_date),max(score) from ranking GROUP BY user_id
      

      结果:

      1   2017-03-04  100.00
      2   2017-03-05  100.00
      3   2017-03-06  100.00
      

      select user_id, max(create_date),cast(max(score)  as UNSIGNED) as maxscore from ranking GROUP BY user_id
      

      结果:

      1   2017-03-04  100
      2   2017-03-05  100
      3   2017-03-06  100
      

      【讨论】:

      • @tim 我只是在关注这个“最近的得分最高的日期”
      猜你喜欢
      • 2015-10-17
      • 1970-01-01
      • 1970-01-01
      • 2019-03-01
      • 2022-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多