日付や時間って、ただの数字じゃなくて、データの中で超大事な情報のカギなんだよね。現実世界でも日付はよく使うでしょ?たとえば、月ごとの売上分析とか、社員の誕生日でフィルタしたり、時間の間隔を比べたり。日付をうまく扱えると、もっと柔軟なクエリが書けるし、複雑な分析もできるようになるよ。
日付操作が超重要な例:
- 特定の月の売上分析。
- 過去1年で登録したユーザー数のカウント。
- 時間ごとのレポート作成(例:毎月の収入)。
PostgreSQLには日付を扱うための関数がたくさんあるけど、ここでは特に便利なやつだけ紹介するね。
日付・時間を扱う基本的な関数
NOW() 関数は、データベースサーバーの現在の日付と時間を返してくれる。今の正確な時間が知りたいときに使うよ。たとえば、新しいレコードを作成した時間を記録したいときとか。
SELECT NOW();
結果例:
2023-11-05 15:23:45.123456+00
使い方例: 注文のレコードを現在の日付と時間で挿入したい場合:
INSERT INTO orders (order_id, order_date, total_amount)
VALUES (1, NOW(), 150.00);
コメント:ここで
NOW() は自動的に現在の日付と時間を
order_date カラムに入れてくれるよ。
INSERTの動きについては、次のレクチャーで詳しくやるからお楽しみに :P
CURRENT_DATE 関数
もし時間はいらなくて、日付だけ欲しいなら CURRENT_DATE を使おう。これは年・月・日だけ返すよ。
シンタックス:
SELECT CURRENT_DATE;
結果例:
2023-11-05
使い方例: たとえば、今日の日付のレコードだけ取得したい場合:
SELECT *
FROM orders
WHERE order_date = CURRENT_DATE;
コメント:ここでは
order_date カラムの日付と、今日の日付を比較してるよ。
ちょっとジョークを。NOW() は職場のコーヒーみたいなもん:今すぐ使えるやつ。CURRENT_DATE は壁のカレンダー:日付だけ、余計な情報なし。
DATE_PART() で日付の一部を抜き出す
DATE_PART() 関数は、年・月・日・時・分みたいに、日付の特定の部分だけを取り出せる。たとえば、特定の年の注文数を数えたり、曜日を調べたりするのに便利!
シンタックス:
DATE_PART('パーツ', 日付)
例:
SELECT DATE_PART('year', NOW()) AS current_year;
結果例:
| current_year |
|---|
| 2025 |
抜き出せる日付のパーツ:
year: 年。month: 月。day: 日。hour: 時。minute: 分。second: 秒。dow: 曜日(0 = 日曜日)。
例2:今月を抜き出す。
SELECT DATE_PART('month', CURRENT_DATE) AS current_month;
結果:
| current_month |
|---|
| 6 |
DATE_PART() は複雑な計算にも使えるよ。たとえば:
今年生まれのユーザーだけ選びたい場合:
SELECT *
FROM students
WHERE DATE_PART('year', birth_date) = DATE_PART('year', CURRENT_DATE);
結果例:
| id | first_name | last_name | birth_date | grade |
|---|---|---|---|---|
| 1 | Otto | Art | 2025-03-12 | 9 |
| 2 | Anna | Pal | 2025-07-08 | 8 |
| 3 | Piu | Wolf | 2025-01-22 | 10 |
| 4 | Eva | Go | 2025-09-30 | 7 |
| 5 | Dan | Sok | 2025-06-14 | 9 |
実践例
このあと出てくる例には、まだ習ってないオペレーターも出てくるけど、心配しなくてOK!すぐにこういう例も余裕で書けるようになるから。リアルな例をたくさん見せたいし、ちょっとワクワクしてもらいたいんだ :)
例1:ユーザーの年齢を計算する
たとえば、users テーブルに各ユーザーの誕生日が入ってるとする。その年齢を計算したい!
クエリ:
SELECT user_id, first_name, last_name,
DATE_PART('year', CURRENT_DATE) - DATE_PART('year', birth_date) AS age
FROM users;
単純に現在の年から誕生年を引いてるだけ。これでざっくり年齢が出せるけど、正確じゃない場合もあるから注意。
結果例:
| user_id | first_name | last_name | age |
|---|---|---|---|
| 101 | Alex | Lin | 25 |
| 102 | Maria | Chi | 30 |
| 103 | Tor | Coz | 22 |
| 104 | Nat | Ive | 27 |
| 105 | Don | Sok | 35 |
例2:時間でフィルタする
たとえば、直近1時間で作られた注文だけ選びたい場合:
SELECT *
FROM orders
WHERE order_date >= NOW() - INTERVAL '1 hour';
INTERVAL(時間の間隔指定)がめっちゃ便利なのが分かるでしょ。
例3:月ごとにグループ化
今年の各月ごとの注文数を数えたい場合:
SELECT DATE_PART('month', order_date) AS order_month, COUNT(*) AS order_count
FROM orders
WHERE DATE_PART('year', order_date) = DATE_PART('year', CURRENT_DATE)
GROUP BY DATE_PART('month', order_date)
ORDER BY order_month;
月番号でグループ化して、結果もその順で並べてるよ。
結果例:
| order_month | order_count |
|---|---|
| 1 | 120 |
| 2 | 95 |
| 3 | 134 |
| 4 | 110 |
| 5 | 42 |
例4:曜日を抜き出す
どの曜日に注文が一番多いか知りたい場合:
SELECT DATE_PART('dow', order_date) AS day_of_week, COUNT(*) AS order_count
FROM orders
GROUP BY DATE_PART('dow', order_date)
ORDER BY order_count DESC;
DATE_PART('dow') は各注文の曜日を数字で返すよ。0が日曜日、1が月曜日、って感じ。DOWはDayOfWeek(曜日)の略ね。
結果例:
| day_of_week | order_count |
|---|---|
| 5 | 210 |
| 4 | 190 |
| 3 | 175 |
| 2 | 160 |
| 1 | 140 |
| 6 | 120 |
| 0 | 95 |
よくあるミスに注意!
日付操作は、ミスしやすくて頭が痛くなることも多い。よくあるトラブルをいくつか紹介するね:
時間・日付のフォーマット: NOW() みたいに日付+時間を返す関数を使うときは、フォーマットに注意しよう。たとえば、order_date と CURRENT_DATE を比較するなら、時間部分が無視されてるか、ちゃんと指定してるか確認してね。
文字列としての日付: データベースによっては、日付がテキスト(文字列)で保存されてることもある。そういう場合、DATE_PART() みたいな日付関数を使うとエラーになるよ。データ型が DATE か TIMESTAMP になってるかチェックしよう。
タイムゾーンの違い: サーバーが1つのタイムゾーンで動いてて、データが別のタイムゾーンから集まってくると、混乱の元になる。TIMESTAMPTZ(タイムゾーン付きタイムスタンプ)の利用も検討してみて!
GO TO FULL VERSION