博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SQL 求解每月周末天数
阅读量:6197 次
发布时间:2019-06-21

本文共 3280 字,大约阅读时间需要 10 分钟。

用一段 SQL 查询某月的周末(包含周六,周日)的天数。

用到的方法:

1 多种日期函数

2 Tally Table 校验

原理:

1 求得每月有多少天数

2 计算第一个完整的自然周需要补齐多少天, 并计算本周的实际周末天数

3 将剩下的天数(月总天数- 补掉的天数)除以 7 , 余数为 0 则取商数 * 2 作为周末天数, 余数不为0, 则去商数 * 2 + 1 作为周末天数

------  代码实现部分  ---------

为了检验算法的正确性,需要统计出 2014 年到 2018 年的每月周末数量,可以用 Tally Table 计算. Tally Table 的概念,在这篇文章中说得清楚:

/*--------------------------

  1. Tally Table 生成 2014 年到 2018 年的日期基础表

  2. 统计基础表每月的假日数目

  3. 对比求解每月假日数目的 SQL 脚本

--------------------------/

-- 此处是 1. Tally Table 生成 2014 年到 2018 年的日期基础表 和 2. 统计基础表每月的假日数目

CREATE TABLE FctMonthlyWeekEnds ( CURR_YEAR INT, CURR_MONTH INT, Monthly_WeekEnd_Count INT) 

DECLARE @BEGIN DATETIME = DATEADD(D,-1,'2014-01-01')
,@END DATETIME = '2018-12-31'
DECLARE @INC INT;
SELECT @INC = DATEDIFF(DAY, @BEGIN, @END);

WITH L0

AS (SELECT * FROM ( VALUES (1) ,(2) ,(3)) AS T(C)),L1 AS (SELECT a.C,b.C AS BC  FROM L0 AS a  CROSS JOIN L0 AS b),L2 AS (SELECT a.C
 ,b.C AS BC  FROM L1 AS a  CROSS JOIN L1 AS b) ,L3 AS (SELECT a.C,b.C AS BC  FROM L2 AS a CROSS JOIN L2 AS b) ,L4 AS (SELECT a.C,b.C AS BC
FROM L3 AS a   CROSS JOIN L3 AS b),L5 AS (SELECT a.C,b.C AS BC FROM L4 AS a   CROSS JOIN L4 AS b)
INSERT INTO FctMonthlyWeekEnds(CURR_YEAR,CURR_MONTH,Monthly_WeekEnd_Count)
SELECT CURR_YEAR, CURR_MONTH, SUM(dayOfWeek_Flag) AS Monthly_WeekEnd_Count
FROM ( SELECT TOP (@INC)   DATEPART(YEAR,DATEADD(DAY, RNK, @BEGIN) ) AS CURR_YEAR
 ,DATEPART(MONTH,DATEADD(DAY, RNK, @BEGIN) ) AS CURR_MONTH
 , DATEADD(DAY, RNK, @BEGIN) AS CURR_DATE,CASE 
 WHEN DATEPART(DW,DATEADD(DAY, RNK, @BEGIN) ) IN(1,7)  THEN 1 ELSE 0 
   END AS dayOfWeek_Flag    FROM ( SELECT ROW_NUMBER() OVER (ORDER BY ( SELECT NULL)) AS RNK   FROM L5) M  ORDER BY RNK) TMP 
GROUP BY CURR_YEAR,CURR_MONTH 
ORDER BY CURR_YEAR,CURR_MONTH

--3. 对比求解每月假日数目的 SQL 脚本,同样计算 2014 年到 2018 年的每月周末假期数目CREATE TABLE FctMonthlyWeekEnds_t ( CURR_YEAR INT, CURR_MONTH INT, Monthly_WeekEnd_Count INT) 

DECLARE @CURR_DAY DATETIME = CONVERT(DATE,'2014-01-05')  DECLARE @CURR_MONTH_BEGIN_DAY DATETIME = DATEADD(DAY,-1* DAY(@CURR_DAY) + 1, @CURR_DAY)  DECLARE @NEXT_MONTH_BEGIN_DAY DATETIME = DATEADD(MONTH,1,@CURR_MONTH_BEGIN_DAY)  DECLARE @CURR_MONTH_DAY_COUNT INT = DATEDIFF(DAY,@CURR_MONTH_BEGIN_DAY,@NEXT_MONTH_BEGIN_DAY)   DECLARE @CURR_MONTH_REST_DAY INT = 0   WHILE (YEAR(@CURR_DAY)<2019)  BEGIN   SET @CURR_MONTH_REST_DAY = DATEPART(DW,@CURR_MONTH_BEGIN_DAY ) - 8 + @CURR_MONTH_DAY_COUNT  INSERT INTO FctMonthlyWeekEnds_t(CURR_YEAR,CURR_MONTH,Monthly_WeekEnd_Count)  SELECT YEAR(@CURR_DAY) AS C_YEAR,MONTH(@CURR_DAY) AS C_MONTH,HEAD_COUNT + BODY_COUNT    FROM (SELECT CASE WHEN DATEPART(dw, @CURR_MONTH_BEGIN_DAY) = 1 THEN 2   ELSE 1   END AS HEAD_COUNT,   CASE WHEN (@CURR_MONTH_REST_DAY) % 7 = 0 THEN (@CURR_MONTH_REST_DAY / 7 )*2   ELSE  FLOOR(@CURR_MONTH_REST_DAY / 7 ) * 2   + 1   END AS BODY_COUNT) T  SELECT @CURR_DAY = DATEADD(MONTH,1,@CURR_DAY)  SELECT @CURR_MONTH_BEGIN_DAY   = DATEADD(DAY,-1* DAY(@CURR_DAY) + 1, @CURR_DAY)  SELECT @NEXT_MONTH_BEGIN_DAY   = DATEADD(MONTH,1,@CURR_MONTH_BEGIN_DAY)  SELECT @CURR_MONTH_DAY_COUNT   = DATEDIFF(DAY,@CURR_MONTH_BEGIN_DAY,@NEXT_MONTH_BEGIN_DAY)   END

-- 对比校验

SELECT T.*, S.*  FROM FctMonthlyWeekEnds_t T INNER JOIN  FctMonthlyWeekEnds S ON T.CURR_YEAR = S.CURR_YEAR AND T.CURR_MONTH  = S.CURR_MONTH WHERE S.Monthly_WeekEnd_Count <> T.Monthly_WeekEnd_Count

 

转载于:https://www.cnblogs.com/Ryanhe/p/9585067.html

你可能感兴趣的文章
【转】自定义UITableViewCell控件阻挡回调不到didSelectRowAtIndexPath的解决办法
查看>>
将 SQL Server Express 版用于 ASP.NET (Visual Studio)
查看>>
Print Visual Tree
查看>>
获取AndroidManifest里的信息
查看>>
【翻译】Windows8支持WebSocket(相关技术)
查看>>
【Android LibGDX游戏引擎开发教程】第07期:中文字体的显示和绘制(上)
查看>>
ubuntu 12.04亮度无法调节和无法保存屏幕亮度解决办法(echo_brightness)
查看>>
jquery插件开发(checkbox全选的简单实例)
查看>>
五大常用算法之二:动态规划算法(DP)
查看>>
<<一种基于δ函数的图象边缘检测算法>>一文算法的实现。
查看>>
9款很酷炫jQuery/HTML5特效应用 有源码哦~
查看>>
VS2010安装与测试编译问题(fatal error LNK1123: failure during conversion to COFF: file invalid or corrupt)...
查看>>
Rhythmk 学习 Hibernate 09 - Hibernate HQL
查看>>
Hive 实现HBase 数据批量插入
查看>>
cidaemon.exe进程cpu占用率高及关闭cidaemon.exe进程方法
查看>>
JarSearch
查看>>
C#调用Winrar实现解压缩
查看>>
Android Google Map v2具体解释:开发环境配置
查看>>
一小时包教会 —— webpack 入门指南
查看>>
堆排序
查看>>