日付関数の書き方 - 日付関数の方言 (NOW / DATE_ADD / TO_CHAR)
現在時刻・日付加算・フォーマットは RDBMS 差分が大きい。NOW / GETDATE / CURRENT_TIMESTAMP、INTERVAL / DATE_ADD / DATEADD を比較
概念図
構文
sql
NOW() / GETDATE() / CURRENT_TIMESTAMP — DATE_ADD / DATEADD / + INTERVALサンプル
3 つの代表操作(現在時刻 / 加算 / フォーマット)の RDBMS 別記法
sql
-- 現在時刻
SELECT NOW(); -- PostgreSQL, MySQL
SELECT CURRENT_TIMESTAMP; -- 全 RDBMS 共通 (ANSI)
SELECT GETDATE(); -- SQL Server
SELECT datetime('now'); -- SQLite
-- 3 日後
SELECT NOW() + INTERVAL '3 days'; -- PostgreSQL
SELECT DATE_ADD(NOW(), INTERVAL 3 DAY); -- MySQL
SELECT DATEADD(day, 3, GETDATE()); -- SQL Server
SELECT datetime('now', '+3 days'); -- SQLite
-- フォーマット (2026-04-14 形式)
SELECT TO_CHAR(NOW(), 'YYYY-MM-DD'); -- PostgreSQL / Oracle
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d'); -- MySQL
SELECT FORMAT(GETDATE(), 'yyyy-MM-dd'); -- SQL Server
SELECT strftime('%Y-%m-%d', 'now'); -- SQLite現在時刻を取る関数の違い
ANSI 標準は CURRENT_TIMESTAMP(括弧なしでも可)で、ほぼすべての RDBMS で動きます。迷ったら CURRENT_TIMESTAMP を使うのが最も移植性が高いです。
NOW() は PostgreSQL と MySQL で有効、GETDATE() は SQL Server 固有、SYSDATE は Oracle。SQLite は関数名ではなく datetime('now') や CURRENT_TIMESTAMP を使います。
日付加算の比較表
| RDBMS | 3 日後 | 1 ヶ月後 |
|---|---|---|
| PostgreSQL | NOW() + INTERVAL '3 days' | NOW() + INTERVAL '1 month' |
| MySQL | DATE_ADD(NOW(), INTERVAL 3 DAY) | DATE_ADD(NOW(), INTERVAL 1 MONTH) |
| SQLite | datetime('now', '+3 days') | datetime('now', '+1 month') |
| SQL Server | DATEADD(day, 3, GETDATE()) | DATEADD(month, 1, GETDATE()) |
| Oracle | SYSDATE + 3 (日単位の数値加算) | ADD_MONTHS(SYSDATE, 1) |
フォーマット指定子の比較
| RDBMS | 関数 | 年月日の指定子 |
|---|---|---|
| PostgreSQL / Oracle | TO_CHAR(dt, fmt) | YYYY-MM-DD HH24:MI:SS |
| MySQL | DATE_FORMAT(dt, fmt) | %Y-%m-%d %H:%i:%s |
| SQL Server | FORMAT(dt, fmt) (.NET 風) | yyyy-MM-dd HH:mm:ss |
| SQLite | strftime(fmt, dt) | %Y-%m-%d %H:%M:%S |
タイムゾーンの落とし穴
- MySQL の
TIMESTAMP: セッションのtime_zoneで自動変換される。DATETIMEは変換されない。混在させると原因不明のズレが起きる - PostgreSQL の
timestamptz: 保存は常に UTC、表示時にクライアント TZ で変換。timestamp(without time zone)との混在に注意 - SQL Server の
GETDATE(): サーバのローカル時刻。UTC が欲しいときはSYSUTCDATETIME()を使う - SQLite: タイムゾーン型が無い。文字列として保存し、
datetime('now')は UTC を返す('localtime'修飾子で変換) - SQL Server の
FORMAT()は遅い: 大量行で呼ぶと CLR オーバーヘッドで顕著に遅くなる。必要ならCONVERT(varchar, dt, 120)で十分な場合が多い
