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,而不是一个日期值;不过,这一步不是必需的。