这应该很容易,甚至可能是重复的,但我的大脑和我的搜索引擎今天都没有多大帮助。
我的问题如下:
给定两个表,它们都有:
- 开始日期
- 停止日期
- 员工的财产。假设表 A 中的办公桌号和表 B 中的团队
- 员工的唯一ID号。
以某种诚实的方式将两个表连接在一起,这样结果表中的每一行只需要一个开始日期和结束日期。
输入和所需输出示例: 表A:
开始日期 停止日期 身份证 服务台号码 01/20 05/20 0100 55 03/20 06/20 0100 56 02/22 04/22 0200 91
表 B(注意员工 0100 的日期重叠):
开始日期 停止日期 身份证 团队编号 01/20 04/20 0100 2 02/20 06/20 0100 3 02/22 04/22 0200 8
输出示例:
开始日期 停止日期 身份证 服务台号码 团队编号 01/20 04/20 0100 55 2 02/20 05/20 0100 55 3 02/20 06/20 0100 56 3 02/22 04/22 0200 91 8
一旦表正确连接,我就可以处理结果日期,但连接本身给我带来了问题。我只是不知道如何确保某些超出范围的日期不会滑入。我目前的连接解决方案(我不确定)就是加入
[Table A].[Start Date] <= [Table B].[Stop Date]
[Table B].[Start Date] <= [Table A].[Stop Date]
然后适当地取最大/最小日期(不用担心那部分,我只关心连接),但我非常怀疑解决方案真的那么简单。
假设我在这里没有出错,所需的输出应该是
开始日期 停止日期 身份证 服务台号码 团队编号 01/20 04/20 0100 55 2 02/20 05/20 0100 55 3 03/20 04/20 0100 56 2 03/20 06/20 0100 56 3 02/22 04/22 0200 91 8
您对连接的直觉确实是正确的,这会产生正确的结果:
SELECT CASE
WHEN teams.start_date > desks.start_date
THEN teams.start_date
ELSE desks.start_date
END start_date
, CASE
WHEN teams.stop_date < desks.stop_date
THEN teams.stop_date
ELSE desks.stop_date
END stop_date
, desks.id
, desks.desk_number
, teams.team_number
FROM desks
JOIN teams
ON desks.start_date < teams.stop_date
AND teams.start_date < desks.stop_date
AND teams.id = desks.id
这应该很容易,甚至可能是重复的,但我的大脑和我的搜索引擎今天都没有多大帮助。
花了两年时间,我的大脑终于开始运转了。 Aaron Bertrand 在这里很好地介绍了这一点。引用他的话
真正重要的是,Event2 在 Event1 开始的同时或之后结束 - 无论它是在早期边界、内部、后期边界还是之后结束,都无关紧要。同样,Event2 需要在 Event1 结束之前或事件 1 结束时开始 - 无论它是在 Event2 之前、在早期边界、内部还是在稍后边界开始都没有关系。
这将逻辑简化为:
WHERE (@E2 >= S1 AND @S2 <= E1)
上面的SQL在逻辑上与原问题中的相同
[Table A].[Start Date] <= [Table B].[Stop Date]
[Table B].[Start Date] <= [Table A].[Stop Date]
但写成
[Table B].[Stop Date] >= [Table A].[Start Date]
[Table B].[Start Date] <= [Table A].[Stop Date]