如何获取两个日期范围内的天数?
我有一个 日历 表,其中包含 2021 年 12 月的所有日期(我只会举例说明表中的一些日期,但据了解,它实际上包含该月的所有日期):
ID | 日期 |
---|---|
01 | 2021-12-01 |
02 | 2021-12-02 |
03 | 2021-12-03 |
04 | 2021-12-04 |
05 | 2021-12-05 |
我有users表:
ID | name | num_employee |
---|---|---|
01 | Andrew | 101 |
02 | Mary | 102 |
我有表assistances
ID | date | num_employee |
---|---|---|
01 | 2021-12-03 | 101 |
02 | 2021-12-04 | 101 |
03 | 2021-12-03 | 102 |
04 | 2021-12-04 | 102 |
05 | 2021-12-05 | 101 |
06 | 2021-12-06 | 102 |
我有一个查询来显示员工编号、姓名、出勤天数和缺勤天数:
SELECT u.num_employee,
u.name,
a.date AS attendances,
(SELECT GROUP_CONCAT(DISTINCT EXTRACT(DAY FROM date)) AS date FROM calendar
WHERE date BETWEEN '2021-12-01' AND '2021-12-31'
AND NOT FIND_IN_SET(EXTRACT(DAY FROM date),a.date)) as faults FROM users u
JOIN (SELECT num_employee,
GROUP_CONCAT(DISTINCT EXTRACT(DAY FROM date)) AS date FROM attendances
WHERE date BETWEEN '2021-12-01' AND '2021-12-31'
GROUP BY num_employee) a ON a.num_employee = u.num_employee
通过上述查询,我得到:
num_employee | name | attends | failure |
---|---|---|---|
101 | 安德鲁 | 3,4,5 | 1,2,3,6,7,8,9,10... |
102 | 玛丽 | 3,4,6 | 1,2,5,7,8,9,10... |
现在,重点是,除了出勤表之外,我还必须考虑另一个名为假期的表。该表的结构如下:
id | initial_date | Final_date | num_employee |
---|---|---|---|
01 | 2021-12-07 | 2021-12-09 | 101 |
02 | 2021-12-07 | 2021-12-09 | 102 |
考虑到该表,范围内的天数处理为假期应该停止出现在“故障”列中。结果应如下:
num_employee | name | attends | failure |
---|---|---|---|
101 | Andrew | 3,4,5 | 1,2,3,6,10... |
102 | Mary | 3,4,6 | 1,2,5,10... |
我怎样才能调整我的查询以获得上述内容?
考虑到我正在使用的 MariaDB 版本,有问题的查询无法适应使用 CTE。我正在开发 phpMyAdmin。
I have the calendar table with all the dates of the month of December 2021 (I will only exemplify some dates within the table, but it is understood that it actually contains all the days of said month):
ID | date |
---|---|
01 | 2021-12-01 |
02 | 2021-12-02 |
03 | 2021-12-03 |
04 | 2021-12-04 |
05 | 2021-12-05 |
I have the users table:
ID | name | num_employee |
---|---|---|
01 | Andrew | 101 |
02 | Mary | 102 |
I have the table assistances
ID | date | num_employee |
---|---|---|
01 | 2021-12-03 | 101 |
02 | 2021-12-04 | 101 |
03 | 2021-12-03 | 102 |
04 | 2021-12-04 | 102 |
05 | 2021-12-05 | 101 |
06 | 2021-12-06 | 102 |
I have a query to display the employee number, their name, the days they attended and the days they were absent:
SELECT u.num_employee,
u.name,
a.date AS attendances,
(SELECT GROUP_CONCAT(DISTINCT EXTRACT(DAY FROM date)) AS date FROM calendar
WHERE date BETWEEN '2021-12-01' AND '2021-12-31'
AND NOT FIND_IN_SET(EXTRACT(DAY FROM date),a.date)) as faults FROM users u
JOIN (SELECT num_employee,
GROUP_CONCAT(DISTINCT EXTRACT(DAY FROM date)) AS date FROM attendances
WHERE date BETWEEN '2021-12-01' AND '2021-12-31'
GROUP BY num_employee) a ON a.num_employee = u.num_employee
With the above query, I get this:
num_employee | name | attendances | faults |
---|---|---|---|
101 | Andrew | 3,4,5 | 1,2,3,6,7,8,9,10... |
102 | Mary | 3,4,6 | 1,2,5,7,8,9,10... |
Now, the point is that in addition to the attendances table, I have to consider another table called vacations. The structure of this table is as follows:
id | initial_date | final_date | num_employee |
---|---|---|---|
01 | 2021-12-07 | 2021-12-09 | 101 |
02 | 2021-12-07 | 2021-12-09 | 102 |
And taking this table into consideration, the days within the ranges that are handled as vacations should stop appearing in the "faults" column. The result should be the following:
num_employee | name | attendances | faults |
---|---|---|---|
101 | Andrew | 3,4,5 | 1,2,3,6,10... |
102 | Mary | 3,4,6 | 1,2,5,10... |
How can I adapt my query to get the above?
The query in question cannot be adapted to use CTE given the version of MariaDB I am using. I am working on phpMyAdmin.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
由于 MySQL 和 MariaDB 不擅长处理序列,因此最好有一个日历表来运行。
因此需要另一个子查询来检索假期日期。
我在子选择中使用了
GROUP BY
,因为一个月内可能有超过 1 个假期。db<>fiddle 此处
FIND_IN_SET 需要一个字符串,不能与
NULL
一起使用,所以你需要检查 NULL 值并替换它们db<>fiddle 此处
As MySQL and MariaDB are bad with sequences, it is good that you have a calendar table to run against.
So another subquery that retrieves the dates of the vacation is needed.
I used a
GROUP BY
in the subselect as there could be more than 1 vacation period in a month.db<>fiddle here
FIND_IN_SET needs a string and doesn't work with
NULL
, so you need to check for NULL Values and replace themdb<>fiddle here