【问题标题】:How to find the max value of val1 where val2 is the maximum?如何找到 val1 的最大值,其中 val2 是最大值?
【发布时间】:2018-08-04 06:54:04
【问题描述】:

Sybase DBMS

在我的玩家表中,我有 4 列:

  1. 播放器
  2. 得分
  3. post_dt
  4. add_dt

如果我想找到post_dt是最大值的玩家的分数,add_dt是那个post_dt和那个玩家的最大值,我该怎么做?我的以下查询需要很长时间才能运行,并且可能效率不高。

select player, score from tb t1 
where post_dt in 
      (select max(add_dt) 
       from tb t2 
       where t1.player = t2.player and t2.post_dt in 
             (select max(post_dt) 
              from tb t2 
              where t1.player = t2.player))

表格

PLAYER    SCORE POST_DT      ADD_DT 

001         15  2017-02-01   2017-01-15
001         26  2017-02-01   2017-01-17  
001         31  2017-01-28   2017-01-10
002         4   2017-03-25   2017-02-25  
002         14  2017-03-25   2017-02-13
002         27  2017-03-25   2017-03-05
003         31  2017-01-02   2016-12-25
003         4   2017-01-03   2016-12-25

查询的预期结果:

01, 26, 2017-02-01, 2017-01-17
02, 27, 2017-03-25, 2017-03-05
03,  4, 2017-01-03, 2016-12-25

【问题讨论】:

  • 你的 dbms 是什么?
  • 你能详细说明一下吗,最好是一些示例数据。很难理解您的要求。
  • 哪个 Sybase RDBMS 产品(ASE?SQLAnywhere?IQ?Advantage?)和版本?除了Cetin的评论,请阅读How to create a Minimal, Complete and Verifiable example,然后回来更新你的问题
  • 我用示例数据更新了我的帖子。

标签: sql sybase


【解决方案1】:

您可以通过使用相关子查询来实现这一点。

SELECT t1.player,
       t1.score
       FROM tb t1
       WHERE t1.post_dt = (SELECT max(t2.post_dt)
                                  FROM tb t2
                                  WHERE t2.player = t1.player)
             AND t1.add_dt = (SELECT max(t2.add_dt)
                                     FROM tb t2
                                     WHERE t2.player = t1.player
                                           AND t2.post_dt = t1.post_dt);

或者,如果您的 DBMS 支持窗口函数,请使用 rank() 窗口函数。

SELECT x.player,
       x.score
       FROM (SELECT t.player,
                    t.score,
                    rank() OVER (PARTITION BY t.player
                                 ORDER BY t.post_dt DESC,
                                          t.add_dt DESC) r
                    FROM tb t) x
       WHERE x.r = 1;

另一种选择是内部连接子查询,它们分别通过playerplayerpost_dt 构建最大值。

SELECT t1.player,
       t1.score
       FROM tb t1
            INNER JOIN (SELECT t2.player,
                               max(t2.post_dt) post_dt
                               FROM tb t2
                               GROUP BY t2.player) t3
                       ON t3.player = t1.player
                          AND t3.post_dt = t1.post_dt
            INNER JOIN (SELECT t3.player,
                               t3.post_dt,
                               max(t3.add_dt) add_dt
                               FROM tb t3
                               GROUP BY t3.player,
                                        t3.post_dt) t4
                       ON t4.player = t1.player
                          AND t4.post_dt = t1.post_dt
                          AND t4.add_dt = t1.add_dt;

【讨论】:

  • 这太棒了!谢谢你。我使用了您的第二个解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-04
  • 2019-05-23
  • 2012-06-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多