【问题标题】:Find overlapping date range from a data set从数据集中查找重叠的日期范围
【发布时间】:2015-07-06 19:42:21
【问题描述】:
p_id    book_num conf_num   arrival_dt  departure_dt    create-dt   room_num
353     21807    3328568    19-JUN-15   21-JUN-15       27-JUN-15   2408
353     21807    3328562    18-JUN-15   20-JUN-15       27-JUN-15   2408

在上面的例子中,arrival_dt 和 leave_dt 重叠了 2 个不同的 同一房间号2408的确认号码

我还想排除以下到达_dt 和离开_dt 相同的记录集

p_id    book_num conf_num   arrival_dt  departure_dt    create-dt   room_num
353     21802    3328508    18-JUN-15   21-JUN-15       27-JUN-15   1909    
353     21802    3328555    18-JUN-15   21-JUN-15       27-JUN-15   1909

你能帮我用一个 SQL 逻辑在表中找到这些记录吗

【问题讨论】:

  • 简单的自我加入。 where parent.arrival_dt between child.arrival_dt and child.departure.dt OR parent.departure_dt between child...

标签: sql oracle date range


【解决方案1】:

SQL Fiddle

Oracle 11g R2 架构设置:

CREATE TABLE TEST ( p_id, book_num, conf_num, arrival_dt, departure_dt, create_dt, room_num ) AS
          SELECT 353, 21807, 3328568, DATE '2015-06-19', DATE '2015-06-21', DATE '2015-06-27', 2408 FROM DUAL
UNION ALL SELECT 353, 21807, 3328562, DATE '2015-06-18', DATE '2015-06-20', DATE '2015-06-27', 2408 FROM DUAL
UNION ALL SELECT 353, 21802, 3328508, DATE '2015-06-18', DATE '2015-06-21', DATE '2015-06-27', 1909 FROM DUAL
UNION ALL SELECT 353, 21802, 3328555, DATE '2015-06-18', DATE '2015-06-21', DATE '2015-06-27', 1909 FROM DUAL
UNION ALL SELECT 353, 21801, 3328444, DATE '2015-06-17', DATE '2015-06-21', DATE '2015-06-27', 2000 FROM DUAL
UNION ALL SELECT 353, 21801, 3328445, DATE '2015-06-18', DATE '2015-06-20', DATE '2015-06-27', 2000 FROM DUAL
UNION ALL SELECT 353, 21803, 3328446, DATE '2015-06-19', DATE '2015-06-20', DATE '2015-06-27', 2001 FROM DUAL
UNION ALL SELECT 353, 21804, 3328447, DATE '2015-06-20', DATE '2015-06-21', DATE '2015-06-27', 2001 FROM DUAL;

查询 1:

SELECT *
FROM   TEST t
WHERE  EXISTS ( SELECT 'X'
                FROM   TEST x
                WHERE  x.room_num     = t.room_num
                AND    x.arrival_dt   < t.departure_dt
                AND    x.departure_dt > t.arrival_dt
                AND NOT (    x.arrival_dt   = t.arrival_dt
                         AND x.departure_dt = t.departure_dt ) )

Results:

| P_ID | BOOK_NUM | CONF_NUM |             ARRIVAL_DT |           DEPARTURE_DT |              CREATE_DT | ROOM_NUM |
|------|----------|----------|------------------------|------------------------|------------------------|----------|
|  353 |    21807 |  3328568 | June, 19 2015 00:00:00 | June, 21 2015 00:00:00 | June, 27 2015 00:00:00 |     2408 |
|  353 |    21807 |  3328562 | June, 18 2015 00:00:00 | June, 20 2015 00:00:00 | June, 27 2015 00:00:00 |     2408 |
|  353 |    21801 |  3328444 | June, 17 2015 00:00:00 | June, 21 2015 00:00:00 | June, 27 2015 00:00:00 |     2000 |
|  353 |    21801 |  3328445 | June, 18 2015 00:00:00 | June, 20 2015 00:00:00 | June, 27 2015 00:00:00 |     2000 |

【讨论】:

    【解决方案2】:

    正确的逻辑是一个在另一个到达之后离开,而第一个在另一个离开之前到达。您可以使用自联接或where 子句来执行此操作。

    如果您只想要记录:

    select r.*
    from records r
    where exists (select 1
                  from records r2
                  where r2.pid = r.pid and
                        r2.arrival_dt >= r.departure_dt and
                        r2.departure_dt <= r.arrival_dt
                 );
    

    【讨论】:

      【解决方案3】:
      SELECT tbl.*
      FROM table tbl
      JOIN table tbl1 ON tbl.p_id= tbl1.p_id
      WHERE tbl.Arrival_dt <= tbl1.Departure_dt
          AND tbl.Departure_dt >= tbl1.Arrival_dt
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-05-27
        • 2014-01-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-19
        • 2015-10-05
        相关资源
        最近更新 更多