我有一张桌子,看起来像:
运动 | 日期 | 每日尝试 |
---|---|---|
足球 | 2021 年 11 月 12 日 | 1 |
足球 | 2023年4月9日 | 1 |
足球 | 2023年4月9日 | 2 |
游泳 | 2022年7月7日 | 1 |
游泳 | 2024年8月8日 | 1 |
游泳 | 2024/08/08 | 2 |
游泳 | 2024/08/08 | 3 |
曲棍球 | 2021 年 11 月 12 日 | 1 |
曲棍球 | 2021 年 11 月 12 日 | 2 |
曲棍球 | 2023年3月5日 | 1 |
对于每项运动,我想选择获取最新日期,以及该日期内 daily_attempt 中的最大记录。所以在上面的例子中我希望输出是
运动 | 日期 | 每日尝试 |
---|---|---|
足球 | 2023年4月9日 | 2 |
游泳 | 2024年8月8日 | 3 |
曲棍球 | 2023年3月5日 | 1 |
最明显的方法是:
SELECT s.sport, s.date, s.MAX(daily_attempt)
FROM table s
INNER JOIN
(
SELECT t.sport, MAX(t.date) max_date
FROM table t
GROUP BY t.sport
) u ON t.sport = u.sport AND s.date = t.max_date
GROUP BY s.sport, s.date
我真的希望有一种更干净和/或更快速的方法来做到这一点。
我有很多这样的表(其中一些确实很大),在某些情况下,我需要对不止一个组和子组进行这种嵌套聚合。
我最初的想法是
SELECT t.sport, t.date, t.daily_attempt
FROM table t
WHERE EXISTS
(
SELECT 1 FROM sport s WHERE s.sport = t.sport AND
GROUP BY s.sport
HAVING t.daily_attempt=MAX(s.daily_attempt) AND t.date = MAX(s.date)
)
但这并不等同。
实际上可以用不同的方式做到这一点吗?我还想到了使用 GROUP BY CUBE 或 GROUP BY ROLLUP 的方法。
使用
row_number()
窗口功能查找每个运动的行及其最新日期等。
select sport, date, daily_attempt
from
(
SELECT sport, date, daily_attempt,
row_number() over
(partition by sport order by date desc, daily_attempt desc) rn
FROM table
) dt
where rn = 1