コードを書いていて、どんな条件式を書けばいいんだっけ?と思ったやつ。
問題
以下の予定の中からxx時 ~ xx時の予定を絞り込むにはどのような条件式を書けばいいか。
タイトル | 開始時刻 | 終了時刻 |
---|---|---|
昼休み | 12:00 | 13:00 |
ミーティング1 | 13:00 | 13:45 |
移動時間 | 13:45 | 14:00 |
ミーティング2 | 14:00 | 15:00 |
(例) 13:30 ~ 13:50の予定 → 「ミーティング1」と「移動時間」
答え
一般化すると、2つの区間 $(a,\ b)$ と $(c,\ d)$ ($a < b, \ c < d$)が交わりを持つ条件を求める問題。
$(a,\ b)$と$(c,\ d)$が交わりを持たない条件を考えてやるとわかりやすい。
2つの区間が交わらないのは、
- $(a,\ b)$が$(c,\ d)$の左側にある時 ($b < c$)
- $(a,\ b)$が$(c,\ d)$の右側にある時 ($d < a$)
のいずれかである。
(求めたい)交わりを持つ条件はこれを否定すればよいので
\lnot\ (\ b < c\ \lor d < a)
\Leftrightarrow c \leq b\ \land a\leq\ d
(※ 等号の有無は細かい要件に合わせればいい)
上の例だと
(検索条件の開始時刻) <= (終了時刻) && (開始時刻) <= (検索条件の終了時刻)
Postgresだと...
Postgresにはtsrange
というtimestampの範囲を表す型があるので簡潔に書けるらしい。
時間のカラム名を仮にperiod
として、[(開始時刻), (終了時刻)]
というtsrange
の値で扱うことにすると
WHERE period && tsrange('2025-8-1 13:30:00', '2025-8-1 13:50:00')
のように一発で書ける。