Ms Access SQL 计算与某些排除期重叠的天数
MsAccess SQL count days in overlaping periods with some excluding periods
问题:
给定一个 table 给定人的时间段可能(或可能不)重叠并给定另一个 table 排除,我想计算每个人的天数以及不包括重叠天数和排除期的期间。
正如他们所说,一张图片值 1000 个字,所以:
- 用绿色画了句号
- 不包括的时期用红色绘制
- 蓝色是解决方案(预期输出,每个周期预计在最终查询中是一行)所以我可以
datediff("d", end_date, start_date)
示例场景:
期间 table:
create table periods (
`id` COUNTER (1,1) PRIMARY KEY,
`person_id` text(50),
`start_date` Date,
`end_date` Date
)
排除期间table:
create table exclusions (
`start_date` As Date,
`end_date` As Date
)
还有一些值:
INSERT INTO `periods`(`person_id`, `start_date`, `end_date`)
VALUES('1', CDate('01/09/2014'), CDate('30/09/2014'));
INSERT INTO `periods`(`person_id`, `start_date`, `end_date`)
VALUES('1', CDate('10/10/2014'), CDate('31/10/2014'));
INSERT INTO `periods`(`person_id`, `start_date`, `end_date`)
VALUES('1', CDate('25/09/2014'), CDate('15/10/2014'));
INSERT INTO `periods`(`person_id`, `start_date`, `end_date`)
VALUES('1', CDate('20/11/2014'), CDate('10/12/2014'));
INSERT INTO `periods`(`person_id`, `start_date`, `end_date`)
VALUES('1', CDate('15/11/2014'), CDate('25/11/2014'));
INSERT INTO `exclusions`(`start_date`, `end_date`)
VALUES(CDate('10/09/2014'), CDate('15/09/2014'));
INSERT INTO `exclusions`(`start_date`, `end_date`)
VALUES(CDate('01/12/2014'), CDate('20/12/2014'));
我试过的:
到目前为止,我能够使用此查询检测重叠时间段:
SELECT s1.person_id as person_id,
iif(s1.start_date <= s2.start_date, s1.start_date, s2.start_date) As start_date,
iif(s1.end_date >= s2.end_date, s1.end_date, s2.end_date) As end_date
FROM
periods As S1 INNER JOIN periods As S2 ON
s1.person_id = s2.person_id And
s1.id < s2.id And
s2.start_date <= s1.end_date And s2.end_date >= s1.start_date
但是有一个问题,结果是:
person_id start_date end_date
1 01/09/2014 15/10/2014
1 25/09/2014 31/10/2014
1 15/11/2014 10/12/2014
请注意,第一行和第二行也是重叠的句点。我可以用它自己的结果来执行相同的查询,但感觉很奇怪。
我需要什么:
我现在遇到的其他问题是我不知道如何:
- 找到不重叠的时期
- 如何用排除日期打破句点
不幸的是,我只能为此使用 MsAccess,所以我不能使用我在谷歌搜索中发现的一些技巧,因此我在这里问。
您可以使用日历 table 来解决这个问题(接下来 'n' 年每天一行)。
create table calendar (
`id` COUNTER (1,1) PRIMARY KEY,
`calendar_date` Date
)
insert into calendar values ('2015-01-01')
insert into calendar values ('2015-01-02')
insert into calendar values ('2015-01-03')
insert into calendar values ('2015-01-04')
insert into calendar values ('2015-01-05') ... et cetera
然后:
select distinct calendar_date
from periods p join calendar c
where c.calendar_date between p.start_date and p.end_date and
not exists(select * from exclusions where c.calendar_date between e.start_date and e.end_date)
问题:
给定一个 table 给定人的时间段可能(或可能不)重叠并给定另一个 table 排除,我想计算每个人的天数以及不包括重叠天数和排除期的期间。
正如他们所说,一张图片值 1000 个字,所以:
- 用绿色画了句号
- 不包括的时期用红色绘制
- 蓝色是解决方案(预期输出,每个周期预计在最终查询中是一行)所以我可以
datediff("d", end_date, start_date)
示例场景:
期间 table:
create table periods (
`id` COUNTER (1,1) PRIMARY KEY,
`person_id` text(50),
`start_date` Date,
`end_date` Date
)
排除期间table:
create table exclusions (
`start_date` As Date,
`end_date` As Date
)
还有一些值:
INSERT INTO `periods`(`person_id`, `start_date`, `end_date`)
VALUES('1', CDate('01/09/2014'), CDate('30/09/2014'));
INSERT INTO `periods`(`person_id`, `start_date`, `end_date`)
VALUES('1', CDate('10/10/2014'), CDate('31/10/2014'));
INSERT INTO `periods`(`person_id`, `start_date`, `end_date`)
VALUES('1', CDate('25/09/2014'), CDate('15/10/2014'));
INSERT INTO `periods`(`person_id`, `start_date`, `end_date`)
VALUES('1', CDate('20/11/2014'), CDate('10/12/2014'));
INSERT INTO `periods`(`person_id`, `start_date`, `end_date`)
VALUES('1', CDate('15/11/2014'), CDate('25/11/2014'));
INSERT INTO `exclusions`(`start_date`, `end_date`)
VALUES(CDate('10/09/2014'), CDate('15/09/2014'));
INSERT INTO `exclusions`(`start_date`, `end_date`)
VALUES(CDate('01/12/2014'), CDate('20/12/2014'));
我试过的:
到目前为止,我能够使用此查询检测重叠时间段:
SELECT s1.person_id as person_id,
iif(s1.start_date <= s2.start_date, s1.start_date, s2.start_date) As start_date,
iif(s1.end_date >= s2.end_date, s1.end_date, s2.end_date) As end_date
FROM
periods As S1 INNER JOIN periods As S2 ON
s1.person_id = s2.person_id And
s1.id < s2.id And
s2.start_date <= s1.end_date And s2.end_date >= s1.start_date
但是有一个问题,结果是:
person_id start_date end_date
1 01/09/2014 15/10/2014
1 25/09/2014 31/10/2014
1 15/11/2014 10/12/2014
请注意,第一行和第二行也是重叠的句点。我可以用它自己的结果来执行相同的查询,但感觉很奇怪。
我需要什么:
我现在遇到的其他问题是我不知道如何:
- 找到不重叠的时期
- 如何用排除日期打破句点
不幸的是,我只能为此使用 MsAccess,所以我不能使用我在谷歌搜索中发现的一些技巧,因此我在这里问。
您可以使用日历 table 来解决这个问题(接下来 'n' 年每天一行)。
create table calendar (
`id` COUNTER (1,1) PRIMARY KEY,
`calendar_date` Date
)
insert into calendar values ('2015-01-01')
insert into calendar values ('2015-01-02')
insert into calendar values ('2015-01-03')
insert into calendar values ('2015-01-04')
insert into calendar values ('2015-01-05') ... et cetera
然后:
select distinct calendar_date
from periods p join calendar c
where c.calendar_date between p.start_date and p.end_date and
not exists(select * from exclusions where c.calendar_date between e.start_date and e.end_date)