T-SQL: 前月の 1 日と末日を取得する方法
SQL で前月の1日と末日を取得するには?
月締めのような処理で、プログラム実行日の前月の 1 ヶ月分のデータを処理しなければならず、前月の 1 日と末日の日付が取得したい時ありますよね。
今回は T-SQLを使って、前月の1日と末日を取得する方法をご紹介します。
DATETIME のデフォルト値を利用して前月の1日と末日を取得する
T-SQLを使って、前月の 1 日と末日を取得するには、複数のファンクションを組み合わせることにより実現でき、何通りも方法があります。
ここでは、DATETIME のデフォルト値を利用した方法を見てみましょう。
前月の 1 日と末日を取得するクエリーは以下の通りです。
DATEADD(MM, DATEDIFF(MM, -1, GETDATE()) - 1, -1) AS 前月末日;
まず、前月 1 日を取得するクエリーから見てみましょう。
DATEDIFF(MM, 0, GETDATE()) の部分ですが、0 が DATETIME の デフォルト値: 1900-01-01 00:00:00.000 で、その日から今日までの月数を取得しています。
そして、それで得られた月数にマイナス 1 した月数を、DateTime の デフォルト値: 1900-01-01 00:00:00.000 に DATEADD で足すことによって、前月の 1 日の日付を取得しています。
つまり、月の部分は 「デフォルトの月 +(デフォルトから今月の月数) - 1」 で先月にし、日の部分はデフォルト値の日の部分 01 をそのまま利用しています。
次に前月末日を取得するクエリーを確認してみましょう。
DATEDIFF(MM, -1, GETDATE()) の部分ですが、この -1 は DATE に変換すると、DateTime の デフォルト値の 1 日前で 1899-12-31 00:00:00.000 です。
ですので、1899-12-31 から今日までの月数を取得し、得られた月数マイナス1 を 1899-12-31 に足すことによって、前月の月末の日付を取得しています。
DATEADD で DatePart に MM (月)を指定し、日の部分が追加後の月に存在しない場合は、その月の一番最後の日が返されます。
例えば、2014-01-31 に DATEADD で 1 ヶ月足すと、 2 月 31 日がないため、以下のように 2014-02-28 となります。
つまり、月の部分は 「デフォルト - 1 の月 +(デフォルト - 1 から今月の月数) - 1」 で先月にし、日の部分はデフォルト -1 の日の部分 31 を DATEADD で利用することによって、その月の最後の日付を取得しています。
参考: DATEDIFF と DATEADD の定義と部分的な実行結果
DATEDIFF ( datepart , startdate , enddate )
DATEADD ( datepart , number , date )
[ 追記 ]
SQL Server 2012 以降では EOMONTH 関数を使って、より簡単に月初と月末の日付を取得することができます。
-> T-SQL: EOMONTH で月初と月末の日付を取得する方法