カレンダーテーブルから閏年を抽出する

前回は再帰クエリを使用して1900年1月1日から9999年12月31日までのカレンダーを作成しました.

現在多くの国で使用されている暦はグレゴリオ暦です.SQL Serverグレゴリオ暦を採用しており,閏年の扱いには以下のような規則があります.

  1. 西暦年が4で割り切れる年は閏年とする.
  2. ただし西暦年が100で割り切れる年は平年とする.
  3. ただし西暦年が400で割り切れる年は閏年とする.

今回は上記の規則に従い閏年を抽出します.


WITH CTE AS
(SELECT YEAR(YMD) AS leap_year,
CASE WHEN YEAR(YMD) % 400 = 0
THEN '閏年'
ELSE CASE WHEN YEAR(YMD) % 100 = 0
THEN '平年'
ELSE CASE WHEN YEAR(YMD) % 4 = 0
THEN '閏年'
ELSE '平年'
END
END
END AS 判定
FROM dbo.T_CALENDAR
GROUP BY YEAR(YMD)
)
SELECT * FROM CTE WHERE 判定 = '閏年');

(1964 行処理されました)

蛇足ですが,以下では2月29日のある年で抽出した結果とグレゴリオ暦閏年の規則で抽出した結果とを比較し,両者が同一であることを証明しています.

WITH CTE AS
(SELECT YEAR(YMD) AS leap_year ,
CASE WHEN YEAR(YMD) % 400 = 0
THEN '閏年'
ELSE CASE WHEN YEAR(YMD) % 100 = 0
THEN '平年'
ELSE CASE WHEN YEAR(YMD) % 4 = 0
THEN '閏年'
ELSE '平年'
END
END
END AS 判定
FROM dbo.T_CALENDAR
WHERE MONTH(YMD) = '2' AND DAY(YMD) = '29'
),
CTE2 AS
(SELECT YEAR(YMD) AS leap_year,
CASE WHEN YEAR(YMD) % 400 = 0
THEN '閏年'
ELSE CASE WHEN YEAR(YMD) % 100 = 0
THEN '平年'
ELSE CASE WHEN YEAR(YMD) % 4 = 0
THEN '閏年'
ELSE '平年'
END
END
END AS 判定
FROM dbo.T_CALENDAR
GROUP BY YEAR(YMD)
),
CTE3 AS
(SELECT * FROM CTE2 WHERE 判定 = '閏年'),
CTE4 AS
(SELECT * FROM CTE
UNION
SELECT * FROM CTE3
),
CTE5 AS
(SELECT * FROM CTE
INTERSECT
SELECT * FROM CTE3
)
SELECT DISTINCT CASE WHEN COUNT(*) = 0 THEN '等しい' ELSE '異なる' END AS 判定
FROM (SELECT * FROM CTE4
EXCEPT
SELECT * FROM CTE5) AS TMP;
(1 行処理されました)

判定
等しい