【问题标题】:How to correctly join two tables that each have Start Date and Stop Date columns?如何正确连接两个表,每个表都有开始日期和结束日期列?
【发布时间】:2022-02-22 06:25:07
【问题描述】:

这应该很容易,甚至可能是重复的,但我的大脑和搜索引擎今天都没有太大帮助。

我的问题如下:

给定两个都有的表:

  1. 开始日期
  2. 停止日期
  3. 员工的财产。假设 A 表中的桌号和 B 表中的团队
  4. 员工的唯一 ID 号。

以某种诚实的方式将这两个表连接在一起,这样结果表中的每一行只需要一个开始和停止日期。

示例输入和所需输出: 表A:

Start Date Stop Date ID Desk Number
01/20 05/20 0100 55
03/20 06/20 0100 56
02/22 04/22 0200 91

表 B(注意员工 0100 的日期重叠):

Start Date Stop Date ID Team Number
01/20 04/20 0100 2
02/20 06/20 0100 3
02/22 04/22 0200 8

示例输出:

Start Date Stop Date ID Desk Number Team Number
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]

然后根据需要取最大/最小日期(不要担心那部分,我只关心连接),但我非常怀疑解决方案是否真的那么简单。

【问题讨论】:

  • 如果日期不连续(即它们只有天精度,而不是(微)秒),那么这两个条件就足够了。对于缺席间隔,您将没有数据,因为没有任何缺席行的来源。您必须自己生成它们(例如,在union 的帮助下),或者使用带有空值/已删除标志的连续间隔来指示没有属性值的行。
  • 这里所需的输出是否错误...?为什么 56 号桌和第 3 组在 02/20 和 06/20 之间?期望的输出不应该包含 03/20 到 04/20 之间的团队 2 和 56 号桌,以及 03/20 到 06/20 之间的团队 3/56 号桌吗?
  • 01/20 这些不是“日期”。谨防过度简化的数据和假设。
  • 使用范围时,请确保您知道您使用的是包含性结束日期还是独占性结束日期。开始日期通常包括在内。结束日期可以是 - 如果结束日期是范围中的最后一个日期,则包括在内;如果结束日期表示桌面或团队关联不再处于活动状态的第一天,则可以是不包括在内。差异决定了您如何对待平等以及在比较中是否应该使用&lt;=&lt;
  • ...(独家结束日期,虽然对人类读者来说不太直观,但在计算方面效果更好。问问自己:今天结束“今天”吗?今天 23:59?在 23:今天 59:59.997?还是明天 00:00:00.000000?另一个问题:2 月 22 日 09:00 是在 2 月 21 日到 2 月 22 日之间吗?)

标签: sql sql-server date tsql join


【解决方案1】:

假设我在这里没有出错,所需的输出应该是

Start Date Stop Date ID Desk Number Team Number
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

Working demo on dbfiddle

【讨论】:

    猜你喜欢
    • 2020-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-16
    • 2022-01-25
    • 1970-01-01
    相关资源
    最近更新 更多