在 SQL 中查找事件之间的最小天数

Posted

技术标签:

【中文标题】在 SQL 中查找事件之间的最小天数【英文标题】:Find Minimum Number of Days Between Events in SQL 【发布时间】:2021-10-30 09:23:02 【问题描述】:

假设我有下表,对于每个玩家,我想知道玩游戏 A 和游戏 B 之间可能的最小差距(天数)。请注意,顺序无关紧要(即,您可以播放 A 后跟 BB 后跟 A)。

Player Date Game
1 2021-01-01 A
1 2021-01-02 A
1 2021-01-08 B
1 2021-01-10 A
2 2021-01-01 A
2 2021-01-02 B
2 2021-01-03 B
2 2021-01-04 A
2 2021-01-05 A
2 2021-01-06 A
2 2021-01-07 A
2 2021-01-08 B
3 2021-01-01 A
3 2021-01-05 B
3 2021-01-07 B
3 2021-01-07 B
3 2021-01-08 B
4 2021-01-01 B
4 2021-01-02 B
4 2021-01-04 A
4 2021-01-07 B

所以,预期的输出是:

Player Days
1 2
2 1
3 4
4 2

我知道我需要执行group-byorder-by

SELECT DO_SOMETHING
FROM PLAY_TABLE
GROUP BY PLAYER
ORDER BY DATE

对于每个组,当相邻行具有不同的 GAME 值时,我似乎需要获取 DATE 的差异,然后返回最小值,但我不清楚如何实现这一点。

【问题讨论】:

也许是自加入? 标记你正在使用的数据库。 游戏是否不止两个? (可以有一个游戏C吗?) 两个游戏,或者相同或不同类型的游戏可以在同一天玩吗? Date 列是否总是只包含一个日期,还是可以/是否还包含一个时间组件? Date 列始终只是一个日期。您可以假设它始终只有游戏A 和游戏B。此外,同一天可以玩多个游戏(A 的全部、B 的全部或AB 的混合)! 【参考方案1】:

最小的间隔将在相邻的行上,因此您可以使用lag()

select player, min(date - prev_date)
from (select t.*,
             lag(game) over (partition by player order by date) as prev_game,
             lag(date) over (partition by player order by date) as prev_date
      from t
     ) t
where prev_game = 'A' and game = 'B' or
      prev_game = 'B' and game = 'A'
group by player;

请注意,众所周知,日期/时间函数依赖于数据库,因此 - 可能无法在您的数据库中使用。

【讨论】:

以上是关于在 SQL 中查找事件之间的最小天数的主要内容,如果未能解决你的问题,请参考以下文章

SQL查找用户分区的两个case语句之间的天数差异

1482. 制作 m 束花所需的最少天数 (Java/c++二分查找)

1482. 制作 m 束花所需的最少天数 (Java/c++二分查找)

查找逾期天数的 SQL 窗口函数

如何从sql中经过的天数中查找年份和月份

SQL查询以查找列的行值之间的最小差异