本連載はSQLの応用力を身に付けたいエンジニア向けに、さまざまなテクニックを紹介する。SQLの基本構文は平易なものだが、実務で活用するには教科書的な記述を理解するだけでは不十分だ。本連載は、著名なメールマガジン「おら!オラ! Oracle - どっぷり検証生活」を発行するインサイトテクノロジーのコンサルタントを執筆陣に迎え、SQLのセンス向上に役立つ大技小技を紹介していく。(編集局)
今回は、データベースに必ず付いてくる(?)日付データを取り扱うSQLについて解説します。日付データは、スケジュール管理や日付、期間ごとの集計、あるいは、特定の期間を過ぎたデータを対象としたメンテナンスなど、データそのものとして、また、ある種のデータを取り扱うために必要不可欠なキーとして重要なデータです。
しかし、普通の数値と同じように扱うには、少し厄介ですね。その最たるところは、日付データの演算です。60進法、24進法、はたまた各月の日数が異なるなど、一筋縄ではいかないことは皆さんも重々ご承知のことでしょう。これをうまく取り扱うため、Oracleには日付データに適したデータ型が用意されています。また、これら日付時刻型のデータを扱うための関数も用意されています。これからOracleに携わる方は必ず覚える必要があります。すでに日付データの扱いに慣れていらっしゃる方も、いま一度整理のためにお付き合いください。
まず初めに、日付データを取り扱う際に注意しておかなくてはいけないパラメータがありますので、これについて整理しておきましょう。
日付フォーマットでよく使うNLSパラメータは以下のとおりです。
NLS関連のパラメータは、下記のビューで確認できます。一度確認してみてください。
今回チェックしておくべきパラメータは、NLS_SESSION_PARAMETERSで確認できます。
SQL> select * from nls_session_parameters; PARAMETER VALUE ------------------------------ ------------------------------ ……略…… NLS_DATE_FORMAT RR-MM-DD NLS_TIMESTAMP_FORMAT RR-MM-DD HH24:MI:SSXFF NLS_TIMESTAMP_TZ_FORMAT RR-MM-DD HH24:MI:SSXFF TZR ……略……
上記のように、日付データの表示フォーマットがNLSパラメータによって定義されています。これらはそれぞれの環境に適切な設定がされるので、同じSQLを実行しても表示が異なり戸惑うことがあります。
では上記を踏まえて、日付データの操作について解説します。まずは、演算方法を見ていきましょう。
Oracle9iからはDATE型に加えて、TIMESTAMP型というデータ型が増えています。これも日付データ型です。取り扱えるデータの精度が異なるのですが、以下の演算についてはDATE型のデータと同様に使用できます。下記には、SYSDATE関数(DATE型)、SYSTIMESTAMP関数(TIMESTAMP型)を使った演算例を挙げます。
【日付データの加(減)算】
日の加(減)算 | ||
---|---|---|
SYSDATE + 1 | SYSTIMESTAMP + 1 (*1) | |
時の加(減)算(1/24) | ||
---|---|---|
SYSDATE + 1/24 | SYSTIMESTAMP + 1/24 (*1) | |
分の加(減)算(1/24/60) | ||
---|---|---|
SYSDATE + 1/24/60 | SYSTIMESTAMP + 1/24/60 (*1) | |
秒の加(減)算(1/24/60/60) | ||
---|---|---|
SYSDATE + 1/24/60/60 | SYSTIMESTAMP + 1/24/60/60 (*1) | |
月の加(減)算(ADD_MONTHS) | ||
---|---|---|
ADD_MONTHS(SYSDATE,1) | ADD_MONTHS(SYSTIMESTAMP,1) (*2) | |
年の加(減)算(ADD_MONTHS) | ||
---|---|---|
ADD_MONTHS(SYSDATE,1*12) | ADD_MONTHS(SYSTIMESTAMP,1*12) (*2) | |
ADD_MONTHS関数の注意事項
第1引数(DATE型)に指定した日がその月の最終日の場合は、結果の日も最終日になります。また、第1引数に指定した日よりも結果の月の日が少ない場合も最終日が結果となります。例えば、第1引数に6月30日、第2引数に1を使用してADD_MONTHS関数を実行すると、その結果は7月31日になります。7月30日ではないので気を付けてください。
(*1)TIMESTAMP WITH TIME ZONE型からDATE型に変換されるので注意。DATE型に変換したくない場合は、後述のTO_DSINTERVAL関数など期間データ型を使用する。
(*2)TIMESTAMP WITH TIME ZONE型からDATE型に変換されるので注意。DATE型に変換したくない場合は、後述のTO_YMINTERVAL関数など期間データ型を使用する。
どうでしょうか。上記の計算方法は比較的よく使います。これが使えれば、アプリケーションで必要な大半の日付処理を記述することが可能ではないでしょうか。演算の単位が1日であるということを認識できれば、覚えるのも簡単ですね。ADD_MONTHS関数は月末日の取り扱いに注意が必要なので、気を付けてください。(次ページへ続く)
Copyright © ITmedia, Inc. All Rights Reserved.