Oracle Databaseで「今日の日付だけを取得したい」ときによく使われるのがTRUNC(SYSDATE)です。OracleのDATE型は年月日だけでなく時・分・秒も保持するため、日付単位で検索や比較をするときには時刻部分の扱いが重要になります。
結論からいうと、TRUNC(SYSDATE)を日単位で実行すると、現在日時の時刻部分が切り捨てられ、その日の00:00:00を表すDATE値になります。ただし、SQLクライアントの表示形式によっては時刻が画面に表示されないことがあるため、「値としての時刻」と「画面上の表示」は分けて理解する必要があります。
TRUNC(SYSDATE)はその日の00:00:00を返す
OracleのSYSDATEは、データベースサーバーが動作しているOSの現在日時をDATE型で返します。例えば現在日時が2026年8月30日23時17分だった場合、概念的には2026-08-30 23:17:00のような値になります。
これに日付用のTRUNC関数を適用すると、指定した単位より細かい部分が切り捨てられます。書式モデルを省略したTRUNC(SYSDATE)では日単位になるため、結果は2026-08-30 00:00:00に相当します。
つまり、TRUNCは文字列から時刻部分を削除しているのではなく、その日の午前0時を表すDATE値へ切り捨てていると考えると理解しやすくなります。
実際にSQLで00:00:00を確認する方法
SELECT TRUNC(SYSDATE) FROM DUAL;を実行しても、環境によっては2026/08/30のように日付だけが表示され、00:00:00が確認できない場合があります。これはNLS_DATE_FORMATなどの表示形式によるものです。
時刻まで明示的に確認したい場合は、TO_CHARで表示形式を指定すると分かりやすくなります。
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') AS current_datetime, TO_CHAR(TRUNC(SYSDATE), 'YYYY-MM-DD HH24:MI:SS') AS truncated_datetime FROM DUAL;
例えば実行時のSYSDATEが2026-08-30 23:17:25なら、TRUNC(SYSDATE)側は2026-08-30 00:00:00と確認できます。Oracle公式のTRUNC(date)の仕様については[参照]も確認できます。
TRUNCはSYSDATE以外のDATE型にも使える
TRUNCはSYSDATE専用ではありません。DATE型のカラムに時刻が保存されている場合にも利用できます。
例えばORDER_DATEに2026-08-30 15:42:18が保存されている場合、TRUNC(ORDER_DATE)は2026-08-30 00:00:00に相当する値になります。
SELECT TO_CHAR(ORDER_DATE, 'YYYY-MM-DD HH24:MI:SS'), TO_CHAR(TRUNC(ORDER_DATE), 'YYYY-MM-DD HH24:MI:SS') FROM ORDERS;
この性質を利用すると、時刻の異なるデータを日単位で扱いやすくなります。
今日のデータを検索するときの使い方
例えばORDER_DATEというDATE型カラムに注文日時が保存されているとします。単純にORDER_DATE = TRUNC(SYSDATE)とすると、その日の00:00:00ちょうどのデータしか一致しません。
日付部分を切り捨てて比較するなら、次のように書くことができます。
SELECT * FROM ORDERS WHERE TRUNC(ORDER_DATE) = TRUNC(SYSDATE);
これなら今日の00:00:00、10:30:00、23:59:59など、時刻が異なるレコードも「今日」として一致します。ただし、大量のデータを検索する場合は、カラム側に関数を適用すると通常のインデックスを効率的に利用できない場合があります。
実務では範囲条件で検索する方法も覚えておく
日時カラムに通常のインデックスが設定されている場合などは、カラムをTRUNCせず、開始日時以上・翌日未満という範囲で検索する方法がよく使われます。
SELECT * FROM ORDERS WHERE ORDER_DATE >= TRUNC(SYSDATE) AND ORDER_DATE < TRUNC(SYSDATE) + 1;
TRUNC(SYSDATE)が今日の00:00:00で、TRUNC(SYSDATE) + 1が翌日の00:00:00なので、「今日の00:00:00以上、明日の00:00:00未満」という条件になります。
終了時刻を23:59:59として検索するより、翌日の00:00:00未満とする考え方のほうが扱いやすいため、日時の範囲検索では覚えておくと便利です。
TRUNCの日付書式を指定すると月初や年初にもできる
TRUNCの第2引数には書式モデルを指定できます。省略した場合は日単位ですが、'MM'を指定すれば月単位、'YYYY'を指定すれば年単位に切り捨てられます。
| SQL | 意味 | 2026-08-30の場合のイメージ |
|---|---|---|
TRUNC(SYSDATE) |
日単位 | 2026-08-30 00:00:00 |
TRUNC(SYSDATE, 'MM') |
月単位 | 2026-08-01 00:00:00 |
TRUNC(SYSDATE, 'YYYY') |
年単位 | 2026-01-01 00:00:00 |
そのため、月初を取得したい処理や月次集計でもTRUNCはよく利用されます。
「時刻が消える」のではなくDATE型として00:00:00になる
Oracleを学び始めたときに混同しやすいのが、DATE型と画面上の文字列表現です。TRUNC(SYSDATE)の結果が30-AUG-26や2026/08/30としか表示されなくても、DATE型から「時刻を格納する場所そのものがなくなった」という意味ではありません。
DATE型の値としては、その日の00:00:00になっています。表示時に時刻部分を見せるかどうかは、セッションの設定やSQLクライアント、TO_CHARで指定した書式などによって変わります。
なお、SYSDATEとCURRENT_DATEは常に同じ意味ではありません。SYSDATEはデータベースサーバーOSの日時、CURRENT_DATEは現在のセッションのタイムゾーンに基づく日時なので、タイムゾーンを扱うシステムでは区別して設計する必要があります。
まとめ:TRUNC(SYSDATE)は今日の00:00:00になる
Oracle SQLで書式モデルを省略してTRUNC(SYSDATE)を実行すると、現在日時の日付部分を残して時・分・秒が切り捨てられ、今日の00:00:00に相当するDATE値になります。
画面に日付しか表示されない場合でも、時刻情報を保持できない型へ変換されたわけではありません。確認するときはTO_CHAR(TRUNC(SYSDATE), 'YYYY-MM-DD HH24:MI:SS')のように表示形式を明示すると分かりやすくなります。
また、今日のレコードを検索する場合はTRUNC(日時カラム) = TRUNC(SYSDATE)だけでなく、性能面も考慮して日時カラム >= TRUNC(SYSDATE) AND 日時カラム < TRUNC(SYSDATE) + 1という範囲条件も使い分けると、実務的なOracle SQLを書きやすくなります。


コメント