我有两个表中包含日期范围,两者之间不一定匹配。我希望得到一个结果,它结合两个表之间的日期范围(和值)。以下是表格中数据的示例:
Table A Table B
+----------+----------+-------+ +----------+----------+-------+
|StartDate | EndDate | Hours | |StartDate | EndDate | Hours |
+----------+----------+-------+ +----------+----------+-------+
|11/02/2014|11/06/2014| 38.75| |11/02/2014|11/02/2014| 7.75|
|12/06/2014|12/10/2014| 23.25| |11/03/2014|11/03/2014| 7.75|
|11/04/2014|11/04/2014| 7.75|
|11/05/2014|11/05/2014| 7.75|
|11/06/2014|11/06/2014| 7.75|
|12/09/2014|12/15/2014| 15.50|
查询的结果应如下所示:
Results
+----------+----------+-------+-------+
|StartDate | EndDate |A Hours|B Hours|
+----------+----------+-------+-------+
|11/02/2014|11/06/2014| 38.75| 38.75|
|12/06/2014|12/15/2014| 23.25| 15.50|
为了使我正在做的更清楚,这里有一些例子:
Table A Table B
+----------+----------+-------+ +----------+----------+-------+
|StartDate | EndDate | Hours | |StartDate | EndDate | Hours |
+----------+----------+-------+ +----------+----------+-------+
|09/01/2014|09/01/2014| 7.75| |09/02/2014|09/02/2014| 7.75|
Results
+----------+----------+-------+-------+
|StartDate | EndDate |A Hours|B Hours|
+----------+----------+-------+-------+
|09/01/2014|09/01/2014| 7.75| Null|
|09/02/2014|09/02/2014| Null| 7.75|
Table A Table B
+----------+----------+-------+ +----------+----------+-------+
|StartDate | EndDate | Hours | |StartDate | EndDate | Hours |
+----------+----------+-------+ +----------+----------+-------+
|08/02/2014|08/02/2014| 7.75| |08/01/2014|08/05/2014| 38.75|
|08/05/2014|08/09/2014| 23.25| |08/08/2014|08/08/2014| 7.75|
| | | | |08/15/2014|08/16/2014| 15.50|
Results
+----------+----------+-------+-------+
|StartDate | EndDate |A Hours|B Hours|
+----------+----------+-------+-------+
|08/01/2014|08/09/2014| 31.00| 46.50|
|08/15/2014|08/16/2014| Null| 15.50|
基本上它归结为我正在尝试建立两个表中可比较日期范围的小时数的详细比较。
到目前为止,我最大的问题是尝试找到一种方法对日期范围的结果进行分组,当结果中每条记录的StartDate和EndDate可能来自表A或表B时,具体取决于具体情况。
答案 0 :(得分:0)
如果开始日期在B
的开始日期和结束日期之间,那么您的逻辑似乎是A
条记录。
select A.StartDate, A.EndDate, A.Hours, sum(B.Hours) as bhours
from A inner join
B
on b.startDate >= a.startDate and b.StartDate <= a.endDate
group by A.StartDate, A.EndDate A.Hours
答案 1 :(得分:0)
好吧,似乎没有一个简单的解决方案,所以我最终提出了一个复杂的解决方案,查询每个可能的场景,并与UNIONs一起使用。
首先,我编写了一个查询,检索了两个表之间完美匹配的所有日期范围
接下来,由于Access不允许FULL OUTER JOIN,我编写了一个LEFT OUTER JOIN查询和一个RIGHT OUTER JOIN查询,它从每个表中检索所有日期范围,与其他表中的日期范围没有任何交集。我加入了表格
(a.StartDate BETWEEN b.StartDate
AND b.EndDate
OR a.EndDate BETWEEN b.StartDate
AND b.EndDate)
然后在where子句中仅指定NULL值。
最后,如果有多个范围一起运行,我必须得到所有相交的日期范围并合并它们,而没有使用递归CTE的好处。我基本上使用外部联接和MIN和MAXing将开始和结束日期嵌套在同一子查询的五个版本中。
答案 2 :(得分:0)
第一步是使用子查询来查找每个段startDate和endDate。
select segments.startDate as StartDate,
segments.endDate as EndDate,
sum(A.hours) as AHours,
sum(B.hours) as BHours
from (
select startDate,
min(endDate) as endDate
from (
select distinct starts.startDate
from (select A.startDate
from A
union all
select B.startDate
from b) as starts
where not exists
(select 1
from A
where A.startDate < starts.startDate
and starts.startDate <= A.endDate)
and not exists
(select 1
from B
where B.startDate < starts.startDate
and starts.startDate <= B.endDate)
) as segmentStarts
inner join (
select distinct ends.endDate
from (select A.endDate
from A
union all
select B.endDate
from b) as ends
where not exists
(select 1
from A
where A.endDate > ends.endDate
and ends.endDate >= A.startDate)
and not exists
(select 1
from B
where B.endDate > ends.endDate
and ends.endDate >= B.startDate)
) as segmentEnds
on segmentStarts.startDate <= segmentEnds.endDate
group by segmentStarts.startDate
) as segments
left join A
on segments.startDate <= A.endDate
and A.startDate <= segments.endDate
left join B
on segments.startDate <= B.endDate
and B.startDate <= segments.endDate
group by segments.startDate, segments.endDate
order by segments.startDate