SQLServerには該当月の日数を求める関数がないので自力で求める必要があります。
指定された月の日数をSQLで求める
SQLServerには該当月の日数を求める関数がないので自力で求める必要があります。
該当月の月初と月末を求め計算する
指定月の月初求める
まずは指定月の月初を求めます。
月初は
Declare @target_date date = GETDATE() SELECT CONVERT( VARCHAR(10), CAST(YEAR(@target_date) AS VARCHAR(4)) + '-' + CAST(MONTH(@target_date) AS VARCHAR(4)) + '-01' ,111 )
で算出します。
内容は指定された月の年月を取り出して「1日」を連結しています。
(後で使いやすいようにCONVERT()関数で日付型に変換しています。)
実行結果は(今日が「2013/12/02」だとすると)
2013-12-01
になります。
指定月の次月の月初求める
次には指定月の次月の月初を求めます。
月初は
Declare @target_date date = GETDATE() SELECT CONVERT( VARCHAR(10), CAST(YEAR(DATEADD(MONTH,1,@target_date)) AS VARCHAR(4)) + '-' + CAST(MONTH(DATEADD(MONTH,1,@target_date)) AS VARCHAR(4)) + '-01' ,111 )
で算出します。
内容は指定された月に+1ヶ月しての年月を取り出して「1日」を連結しています。
(これも後で使いやすいようにCONVERT()関数で日付型に変換しています。)
実行結果は(今日が「2013/12/02」だとすると)
2014-1-01
になります。
次月の1日から今月の1日を引く
上記で求めた次月の1日から今月の1日をDATEDIFF()関数で引くと今月の日数が出てきます。
SQLは
Declare @target_date date = GETDATE() SELECT DATEDIFF(DAY, CONVERT( VARCHAR(10), CAST(YEAR(@target_date) AS VARCHAR(4)) + '-' + CAST(MONTH(@target_date) AS VARCHAR(4)) + '-01' ,111 ) , CONVERT( VARCHAR(10), CAST(YEAR(DATEADD(MONTH,1,@target_date)) AS VARCHAR(4)) + '-' + CAST(MONTH(DATEADD(MONTH,1,@target_date)) AS VARCHAR(4)) + '-01' ,111 ) ) AS 日数
で実行結果は
日数 31
になります。
閏年の計算も可能
閏年もこの処理で正しく日数を取得できます。
まずは普通の年。
Declare @target_date date = CAST('2013/02/02' AS DATE) SELECT DATEDIFF(DAY, CONVERT( VARCHAR(10), CAST(YEAR(@target_date) AS VARCHAR(4)) + '-' + CAST(MONTH(@target_date) AS VARCHAR(4)) + '-01' ,111 ) , CONVERT( VARCHAR(10), CAST(YEAR(DATEADD(MONTH,1,@target_date)) AS VARCHAR(4)) + '-' + CAST(MONTH(DATEADD(MONTH,1,@target_date)) AS VARCHAR(4)) + '-01' ,111 ) ) AS 日数
で実行結果は
日数 28
次は閏年で
Declare @target_date date = CAST('2012/02/02' AS DATE) SELECT DATEDIFF(DAY, CONVERT( VARCHAR(10), CAST(YEAR(@target_date) AS VARCHAR(4)) + '-' + CAST(MONTH(@target_date) AS VARCHAR(4)) + '-01' ,111 ) , CONVERT( VARCHAR(10), CAST(YEAR(DATEADD(MONTH,1,@target_date)) AS VARCHAR(4)) + '-' + CAST(MONTH(DATEADD(MONTH,1,@target_date)) AS VARCHAR(4)) + '-01' ,111 ) ) AS 日数
で実行結果は
日数 29
になり正常に取得できます。
使用上の注意
上記のSQLは月に+1ヶ月するので年月が「9999/12」の時にオーバーフローしてランタイムエラーになります。
「9999/12」がありえる処理の場合はチェックする処理が必要になります。