sql - 选择运动员在过去 3 项比赛中未获得第一名的成绩

标签 sql postgresql window-functions

假设我有一个运动会结果数据库,其模式如下

DATE,NAME,FINISH_POS

我想做一个查询来选择运动员至少参加过三场比赛但没有获胜的所有行。例如使用以下样本数据

2013-06-22,Johnson,2
2013-06-21,Johnson,1
2013-06-20,Johnson,4
2013-06-19,Johnson,2
2013-06-18,Johnson,3
2013-06-17,Johnson,4
2013-06-16,Johnson,3
2013-06-15,Johnson,1

以下行:

2013-06-20,Johnson,4
2013-06-19,Johnson,2

将被匹配。我只设法从以下 stub 开始:

select date,name FROM table WHERE ...;

我一直在努力思考 where 子句,但我什至无法开始

最佳答案

我认为这可以更简单/更快:

SELECT day, place, athlete
FROM  (
   SELECT *, min(place) OVER (PARTITION BY athlete
                              ORDER BY day
                              ROWS 3 PRECEDING) AS best
   FROM   t
   ) sub
WHERE  best > 1

->SQLfiddle

使用聚合函数 min()作为窗口函数获取最后三行加上当前行的最小位置。
由于在 best > 1 之后 应用了窗口函数,因此必须在下一个查询级别完成对“未获胜”( WHERE) 的简单检查条款。所以你至少需要一个CTE子选择条件的窗口函数的结果。

关于 window function calls in the manual here 的详细信息.特别是:

If frame_end is omitted it defaults to CURRENT ROW.

如果place ( finishing_pos ) 可以为 NULL,请改用它:

WHERE  best IS DISTINCT FROM 1

min()忽略 NULL值,但如果框架中的所有行都是 NULL , 结果是 NULL .

不要使用类型名和保留字作为标识符,我用day代替了为你的 date .

假设每天最多有 1 场比赛,否则您必须定义如何处理时间线中的同行或使用 timestamp而不是 date .

@Craig已经提到了使这个速度更快的索引。

关于sql - 选择运动员在过去 3 项比赛中未获得第一名的成绩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17247725/

相关文章:

mysql - 在 GROUP BY 中选择 MAX,但在 MYSQL 中将结果限制为 1

ruby-on-rails - 数据库迁移脚本中断引用

sql - 连接和排序 1 :n relationship 中两个表的不同行

r - 在列中定义的窗口内求和

sql - 根据列值的条件 ORDER BY

sql - 测量两个纬度/经度点之间的距离

mysql - 在mysql中连接具有多个外键的表

postgresql - 从多个 postgres 表中选择数据的最佳实践

python - PySpark 窗口函数 : multiple conditions in orderBy on rangeBetween/rowsBetween

sql - 如何根据范围获取连续的批号?