【问题标题】:Find the overlapping information查找重叠信息
【发布时间】:2020-11-05 13:15:07
【问题描述】:
CREATE temp TABLE players
( 
    id                    smallint,
    player_id            smallint,
    team                 varchar(20),
    start_dt             date,
    end_dt               date
);

insert into players (id, player_id, team, start_dt, end_dt) values 
(1,100,'TEAM-A','2018-01-01','2018-08-15'),
(2,100,'TEAM-B','2018-11-15',NULL),
(3,101,'TEAM-B','2018-05-15','2019-02-15'),
(4,101,'TEAM-C','2019-04-01','2019-09-15'),
(5,101,'TEAM-A','2019-11-01',NULL),
(6,102,'TEAM-B','2018-01-15','2019-02-15'),
(7,102,'TEAM-C','2019-05-15','2019-08-01'),
(8,102,'TEAM-A','2019-09-01', NULL  ),
(9,103,'TEAM-C','2019-01-01','2019-06-15')
;

从上面的示例输入数据中,我需要找到如下重叠信息-

我尝试使用重叠选项来完成此操作,但它没有给我预期的结果。 非常感谢任何输入。

【问题讨论】:

    标签: sql database postgresql date join


    【解决方案1】:

    您正在寻找在给定时间点属于同一支球队的成对球员。

    您可以使用适当的日期重叠条件自联接表,并使用least()greatest() 计算重叠范围。

    select 
        p1.player_id player_id_1,
        p2.player_id player_id_2,
        p1.team,
        greatest(p1.start_dt, p2.start_dt) start_dt,
        least(p1.end_dt, p2.end_dt) end_dt,
        least(p1.end_dt, p2.end_dt) - greatest(p1.start_dt, p2.start_dt) overlaps_interval
    from players p1
    inner join players p2
        on  p1.team = p2.team
        and p1.player_id < p2.player_id
        and coalesce(p1.end_dt, current_date) >= p2.start_dt
        and coalesce(p2.end_dt, current_date) >= p1.start_dt
    order by 1, 2
    

    我通常倾向于避免使用overlaps,因为不等式条件可以更精细地控制边界是包含还是排除。但是如果你想使用它,那么:

    select 
        p1.player_id player_id_1,
        p2.player_id player_id_2,
        p1.team,
        greatest(p1.start_dt, p2.start_dt) start_dt,
        least(p1.end_dt, p2.end_dt) end_dt,
        least(p1.end_dt, p2.end_dt) - greatest(p1.start_dt, p2.start_dt) overlaps_interval
    from players p1
    inner join players p2
        on  p1.team = p2.team
        and p1.player_id < p2.player_id
        and (p1.start_dt, coalesce(p1.end_dt, current_date)) 
            overlaps (p2.start_dt, coalesce(p2.end_dt, current_date))
    order by 1, 2
    

    Demo on DB Fiddle - 两个查询都产生:

    player_id_1 | player_id_2 |团队 |开始_dt | end_dt |重叠间隔 ----------: | ----------: | :----- | :--------- | :--------- | ----------------: 100 | 101 |团队-B | 2018-11-15 | 2019-02-15 | 92 100 | 102 |团队-B | 2018-11-15 | 2019-02-15 | 92 101 | 102 |团队-A | 2019-11-01 | | 101 | 102 |团队-B | 2018-05-15 | 2019-02-15 | 276 101 | 102 |团队-C | 2019-05-15 | 2019-08-01 | 78 101 | 103 |团队-C | 2019-04-01 | 2019-06-15 | 75 102 | 103 |团队-C | 2019-05-15 | 2019-06-15 | 31

    【讨论】:

      猜你喜欢
      • 2018-03-05
      • 2021-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-19
      • 2013-05-09
      • 2023-03-31
      • 2016-06-09
      相关资源
      最近更新 更多