トレーニングは1時間半、仕事の日は8時間、休憩は20分、卵を茹でるのは10分。全部、時間間隔の話だよ。
時間の間隔は、実際のアプリでめっちゃ便利。たとえばタスクの締め切りを計算したり、2つの日付の差を出したり、時間を足したり引いたりしたいときに使うんだ。でも細かい話に入る前に、前回の講義でどこまでやったか軽く思い出そう。
PostgreSQLのINTERVALは、時間の間隔を表すための特別なデータ型だよ。他の時間系データ型と違って、具体的な日付や時刻を保存するんじゃなくて、「2日間」とか「3時間」、「5分」みたいな期間を表現するんだ。
INTERVALの構文
間隔はこんなフォーマットで書くよ:
INTERVAL '数字 時間単位'
例:
INTERVAL '2 days' -- 二日間
INTERVAL '3 hours' -- 三時間
INTERVAL '15 minutes' -- 十五分
INTERVAL '1 day 2 hours' -- 一日と二時間
PostgreSQLは色んな時間単位をサポートしてるよ:year、month、day、hour、minute、second。これらは一つの式で組み合わせて使える。
クエリでのINTERVALの使い方
INTERVALデータ型は、他の時間系データ型(DATE、TIMESTAMP)と組み合わせて使うと特に便利。基本的な操作を見てみよう。
日付や時刻に間隔を追加する
間隔は日付や時刻の値に足せるよ。例えば:
SELECT CURRENT_DATE + INTERVAL '7 days' AS delivery_date;
-- 今から7日後の日付を取得
結果:
| delivery_date |
|---|
| 2023-10-08 |
日付や時刻から間隔を引く
追加だけじゃなくて、間隔を引くこともできる:
SELECT NOW() - INTERVAL '2 hours' AS two_hours_ago;
-- 2時間前の時刻を取得
結果:
| two_hours_ago |
|---|
| 2023-10-01 10:00:00.000 |
2つの日付の差分を計算する
INTERVALの強力な機能の一つが、2つの日付の差を計算すること:
SELECT '2023-10-15'::DATE - '2023-10-01'::DATE AS days_difference;
-- 2つの日付の間に何日あるか
結果:
| days_difference |
|---|
| 14 days |
この場合も、結果は時間間隔として返されることに注意してね。
INTERVALの実践例
配達日の計算。 ネットショップで配達が3日から7日かかるとしよう。こんな感じで配達予定日を計算できるよ:
SELECT CURRENT_DATE + INTERVAL '3 days' AS earliest_delivery,
CURRENT_DATE + INTERVAL '7 days' AS latest_delivery;
結果:
| earliest_delivery | latest_delivery |
|---|---|
| 2023-10-04 | 2023-10-08 |
タスクの完了予定時刻の計算。 例えばtasksテーブルがあって、各タスクの開始日が記録されてるとする。そのタスクの所要時間(時間単位)を考慮して、終了予定日を計算したい場合:
CREATE TABLE tasks (
task_id SERIAL PRIMARY KEY,
task_name TEXT,
start_time TIMESTAMP,
duration INTERVAL
);
INSERT INTO tasks (task_name, start_time, duration)
VALUES
('レポート作成', '2023-10-01 09:00:00', INTERVAL '4 hours'),
('アプリケーションテスト', '2023-10-01 10:00:00', INTERVAL '2 hours 30 minutes');
SELECT task_name,
start_time,
start_time + duration AS end_time
FROM tasks;
結果:
| task_name | start_time | end_time |
|---|---|---|
| レポート作成 | 2023-10-01 09:00:00 | 2023-10-01 13:00:00 |
| アプリケーションテスト | 2023-10-01 10:00:00 | 2023-10-01 12:30:00 |
所要時間の比較。 たとえば、3時間未満で終わったタスクだけを探したいとき:
SELECT task_name
FROM tasks
WHERE duration < INTERVAL '3 hours';
結果:
| task_name |
|---|
| アプリケーションテスト |
INTERVALの便利なテクニック
動的な間隔の計算。 他の操作と組み合わせて間隔を作ることもできる。例えば、カラムから日数を取ってきて、それをINTERVALに変換する:
SELECT CURRENT_DATE + (order_days || ' days')::INTERVAL AS order_due_date
FROM orders;
INTERVALを文字列に変換。 表示用にINTERVALを文字列にしたいときもあるよ:
SELECT INTERVAL '2 days 3 hours'::TEXT AS interval_text;
結果:
| interval_text |
|---|
| 2 days 03:00:00 |
INTERVALでよくあるミス
INTERVALは便利だけど、ちょっとしたミスでハマることもある。よくあるのが、フォーマットを間違えること。例えばINTERVAL '2 hours and 30 minutes'って書くとエラーになるよ。"and"はPostgreSQLが理解できないからね。正しい書き方はINTERVAL '2 hours 30 minutes'。
もう一つのミスは、時間単位を省略しちゃうこと。INTERVAL '2'みたいに書くと、PostgreSQLは「2って何?」ってなる。だから必ず単位を明示しよう(2 days、2 hoursみたいに)。
GO TO FULL VERSION