没有public假期的休假如何总结?

How to summarize leave to without public holidays?

大家好(放假前)

在这种情况下,我在此 table:

添加了新的假期
+--------+---------+---------+-------------+----------+--------------------------
|ID_LEAVE|ID_WORKER| FNAME   | LNAME | BEGIN_DATE         | END_DATE            | 
+--------+---------+---------+---------+-------------+--------------------+------
| 8      |   10    | MARIO   | NEED  |2019-04-22 07:00:00 |2019-04-23 15:00:00  | 
+--------+---------+---------+-------------+----------+-------------------------- 

但我知道假期是这样表示的:

我做了什么?

我做了那个查询,它汇总了按 ID_LEAVE

分组的所有员工的休假时间
SELECT leave.ID_LEAVE, leave.ID_WORKER, workers.FNAME, workers.LNAME, leave.BEGIN_DATE, leave.END_DATE,  
FROM 
(SELECT ADDDATE('1970-01-01', t4 * 10000 + t3 * 1000 + t2 * 100 + t1 * 10 + t0) AS date_value 
 FROM 
(SELECT 0 t0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t0, 
 (SELECT 0 t1 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1, 
 (SELECT 0 t2 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2, 
 (SELECT 0 t3 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t3, 
 (SELECT 0 t4 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t4) calendar 
INNER JOIN leave ON calendar.date_value BETWEEN DATE(leave.BEGIN_DATE) AND DATE(leave.END_DATE) 
INNER JOIN workers ON leave.ID_WORKER = workers.ID_WORKER 
WHERE NOT WEEKDAY(date_value) IN (5, 6)
GROUP BY ID_LEAVE;

现在我想要一个汇总所有员工休假时间但 没有假期的查询,如上图所示。 我该怎么办?我应该创建新的 "holidays" table 然后从此 table 下载该日期还是在上面的查询中添加日期?

如果你有一个日历 table 列出了所有的日子(不仅是假期,还有接下来 X 年的每一天,还有一个列是否是 public 假期等)那么你的查询看起来像

SELECT l.id_leave, count(*)
FROM calendar c INNER JOIN leave l ON c.calendar_date BETWEEN l.start_date AND l.end_date
WHERE c.day_type NOT IN ('publicholiday', 'weekend')
GROUP BY l.id_leave

您可以添加更多的复杂性,但这是核心。不确定为什么你的假期从早上 7 点开始到晚上 10 点结束,但如果你允许小数天休息,你可能想添加一些逻辑 - 将开始日期延长回午夜(这样两者之间的工作正常)然后使用一个案例根据所考虑的日期是开始日期、结束日期还是中间日期来构建分数

没有完整日历的变体 table,但有问题中的假期 table(尽管有完整的日期 - 你必须每年填充它):

SELECT L.id_leave, COUNT(*)
FROM (
    SELECT '1970-01-01' + INTERVAL (seq) DAY AS date
    FROM seq_0_to_24836
) C
INNER JOIN leaves L
    ON C.date BETWEEN L.begin_date AND L.end_date
    AND NOT WEEKDAY(date_value) IN (5, 6)
    AND NOT EXISTS (
        SELECT * FROM holidays H WHERE H.date = C.date
    )
GROUP BY L.id_leave

注意:seq_0_to_24836 是仅限 MariaDB 的扩展,将在此处生成从纪元到 2037 年底的所有日期。

好的,在分析了所有评论和答案后,我找到了解决方案:

1) 我创建了假期 table。

2) 我创建了一个查询,它选择所有内容并汇总 leave_time,没有周末和节假日:

SELECT *, 
TIME_FORMAT(SEC_TO_TIME(SUM(TIME_TO_SEC(TIMEDIFF(TIME(leave.END_DATE), TIME(leave.BEGIN_DATE))))), '%H:%i:%s') AS 'LEAVE TIME' 
FROM 
(SELECT ADDDATE('1970-01-01', t4 * 10000 + t3 * 1000 + t2 * 100 + t1 * 10 + t0) AS date_value FROM 
(SELECT 0 t0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t0, 
(SELECT 0 t1 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1, 
(SELECT 0 t2 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2, 
(SELECT 0 t3 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t3, 
(SELECT 0 t4 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t4) calendar 
INNER JOIN `leave` ON calendar.date_value BETWEEN DATE(leave.BEGIN_DATE) AND DATE(leave.END_DATE) 
WHERE NOT WEEKDAY(date_value) IN (5, 6) AND NOT DATE(date_value) IN (SELECT DATE_HOLIDAY FROM holidays) GROUP BY ID_LEAVE;

我刚刚在下面的链接中进行了测试:

https://dbfiddle.uk/?rdbms=mariadb_10.3&fiddle=a25a3dc5762dba08541c002f12efc024

有人对此有任何警告吗? 非常感谢,祝你复活节愉快 ;)