如何计算除假日和周末之外的两个日期之间的天数?

时间:2018-02-08 09:40:45

标签: mysql mariadb

我开始了一个人力资源管理项目,我想计算两个日期之间的天数而不计算假期和周末。因此,人力资源部门可以计算员工的休假日

在这种情况下,我希望在2018-02-142018-02-20之间计算2018-02-16的办公室假期。结果应该是3天。

我已经创建了一个名为tbl_holiday的表格,我在那里将所有周末和假期放在一年

I found this post,我在我的MariaDB上尝试过它

这是我的疑问:

SELECT 5 * (DATEDIFF('2018-02-20', '2018-02-14') DIV 7) + 
MID('0123444401233334012222340111123400012345001234550', 7 * 
WEEKDAY('2018-02-14') + WEEKDAY('2018-02-20') + 1, 1) - 
(SELECT COUNT(dates) FROM tbl_holiday WHERE dates NOT IN (SELECT dates FROM tbl_holiday)) as Days

查询有效但结果是4天,而不是3天。这意味着查询只排除周末而不是假期

我的查询有什么问题?我错过了什么吗?谢谢你的帮助

2 个答案:

答案 0 :(得分:0)

@RichardDoe,来自问题评论。

在日期表的合理实施中,您创建一个所有天的列表(涵盖足够的范围以应对您可能针对它运行的任何查询 - 从今天起每年15年可能一个有用的最小值),并且每天存储各种派生属性。

我最近编写了一个Q& A,其中包含可以帮助您入门SQL Server的基本工具:https://docs.corda.net/head/corda-configuration-file.html

不幸的是,我没有MySQL环境或熟悉它,允许我编写或调整我的头脑问题(正如我在这里做的那样),但我希望这将说明一个结构SQL Server语法中的解决方案。

就我链接到的答案(即动生成日期表)并通过添加您的假期表(并对您如何定义假期表进行一些推断)来扩展它,并注意到工作日是周一至周五的任何一天,不是假期,你会写一个这样的查询,以获得任意两个日期之间的工作日数:

WITH 
dynamic_date_table AS
(
    SELECT *
    FROM generate_series_datetime2('2000-01-01','2030-12-31',1)
    CROSS APPLY datetime2_params_fxn(datetime2_value)
)
,date_table_ext1 AS
(
    SELECT
        ddt.*
        ,IIF(hol.dates IS NOT NULL, 1, 0) AS is_company_holiday

    FROM 
        dynamic_date_table AS ddt

    LEFT JOIN 
        tbl_holiday AS hol
        ON (hol.dates = ddt.datetime2_value)
)
,date_table_ext2 AS
(
    SELECT
        *
        ,IIF(is_weekend = 1 OR is_company_holiday = 1, 0, 1) AS is_company_work_day
    FROM date_table_ext1
)

SELECT 
    COUNT(datetime2_value)
FROM 
    date_table_ext2
WHERE 
    (datetime2_value BETWEEN '2018-02-14' AND '2018-02-20')
    AND
    (is_company_work_day = 1)

显然,一个经过深思熟虑的解决方案的想法是,这些中间计算(对整个公司来说是一般性的)会被卷入date_params_fxn,因此对数据库运行的任何查询都可以访问预定义的公司工作日列表。对它运行的查询然后开始类似于简单的英语(而不是你在问题中链接和调整的方法,这是巧妙的,但远非清晰)。

如果您想获得最佳性能(如果您大量进行这些计算将会相关),那么您可以定义适当的参数,将批次保存到存储的日期表中,并对该表进行适当的索引。这样,您的查询将变得像查询的最后部分一样简单,但引用存储的日期表而不是with-block。

我在你的问题评论中提到的顺序编号的工作日是针对日期表的某些类型的查询的效率和可索引性的又一步,但我现在不会进一步复杂化这个答案。如果需要进一步澄清,请随时询问。

答案 1 :(得分:0)

我找到了这个问题的答案

事实证明,我只需要使用一个简单的算术运算符来解决这个问题

$