SQL 判断闰年判断当前年份是否闰年。
SQL 判断闰年 问题描述
判断当前年份是否闰年。
SQL 判断闰年 解决方案
如果你已经有了一段时间的 SQL 编程经验,那么你肯定知道本问题有多种解法。我也尝试过多种解决方案,它们都能给出正确答案,但是本实例提供的方案可能是最为简单的。下面的解决方案仅仅检查 2 月的最后一天:如果有 2 月 29 日,则当前年份是闰年。
DB2
使用 WITH
子句递归查询返回 2 月的每一天,然后调用聚合函数 MAX
确认 2 月的最后一天。
Oracle
使用 LAST_DAY
函数找出 2 月的最后一天。
PostgreSQL
使用 GENERATE_SERIES
函数返回 2 月的每一天,然后调用聚合函数 MAX
找出 2 月的最后一天。
MySQL
使用 LAST_DAY
函数找出 2 月的最后一天。
SQL Server
使用 WITH
递归查询返回 2 月的每一天,然后调用聚合函数 MAX
确认 2 月的最后一天。
SQL 判断闰年 扩展知识
DB2
递归视图 X
里的内嵌视图 TMP1
按照下面的步骤返回 2 月的第一天。
(1) 从当前日期开始;
(2) 调用 DAYOFYEAR
函数确认当前日期是当前年份的第几天;
(3) 从当前日期里减去上述步骤算出的那个数字以得到上一年的 12 月 31 日,然后加上 1 天得到当前年份的 1 月 1 日;
(4) 再加上 1 个月得到 2 月 1 日。
上述步骤的运算结果如下所示。
然后,调用 MONTH
函数找出内嵌视图 TMP1
返回的日期对应的月份。
到此为止的结果只是作为生成 2 月的每一天的递归操作的起点。为了获得 2 月的每一天,不断为 DY
加上 1 天,直到月份不再是 2 月为止。该 WITH
计算的部分结果如下所示。
最后,针对 DY
列调用 MAX
函数返回 2 月的最后一天;如果是 29 日的话,则当前年份是闰年。
Oracle
首先,调用 TRUNC
函数找出当前年份的第一天。
由于 1 月 1 日是一年中的第一天,下一步就是在此基础上加上 1 个月得到 2 月 1 日。
然后,调用 LAST_DAY
找出 2 月的最后一天。
最后,调用 TO_CHAR
得到 28 或者 29(这一步不是必需的)。
PostgreSQL
首先观察内嵌视图 TMP1
返回的结果。调用 DATE_TRUNC
函数得到当前年份的第一天,并将其转换为 DATE
类型。
然后,在当前年份第一天的基础上加上 1 个月,得到 2 月的第一天,并转换为 DATE
类型。
接着,从内嵌视图 TMP1
里返回 DY
,并依据 DY
计算出月份的值。调用 TO_CHAR
函数返回月份的值。
到此为止的计算结果构成了内嵌视图 TMP2
的结果集。下一步要用到一个非常有用的函数 GENERATE_SERIES
来生成 29 行数据(值从 1 逐一递增到 29)。GENERATE_SERIES
函数返回的每一行(别名为 X)都和内嵌视图 TMP2
的 DY
相加。部分结果如下所示。
最后,调用 MAX
函数找出 2 月的最后一天。针对该日期值调用 TO_CHAR
函数将得到 28 或者 29。
MySQL
首先找出当前年份的第一天:先计算出当前日期是当前年份的第几天,用当前日期减去该值,然后再加上 1 天。DATE_ADD
函数能完成这一步。
接着,再次调用 DATE_ADD
函数在上述计算结果的基础上加上 1 个月。
现在得到了 2 月 1 日的日期值,接着调用 LAST_DAY
函数找出 2 月的最后一天。
最后,调用 DAY
函数返回 28 或者 29(这一步不是必需的)。
SQL Server
该解决方案利用 WITH
递归查询生成 2 月的每一天。第一步先找出 2 月的第一天。为达到此目的,先找出当前年份的第一天:计算出当前日期是当前年份的第几天,用当前日期减去该值,然后再加上 1 天。既然有了当前年份的第一天,调用 DATEADD
函数加上 1 个月,就能得到 2 月的第一天了。
接着,返回 2 月的第一天,并计算出该日期对应月份的数值形式。
然后利用 WITH
子句的递归特性,不断为内嵌视图 TMP1
返回的 DY
加上 1,直到日期对应的月份不再是 2 月,部分结果如下所示。
现在得到了 2 月的每一天,最后调用 MAX
函数看一下最后一天是 28 日还是 29 日。还可以调用 DAY
函数返回数字 28 或者 29,而不是一个日期值;不过,这一步不是必需的。