SQL에서 날짜 범위의 오버랩 확인

8089 단어 SQL
무엇을 달인지 모르겠지만, 자신의 메모

예약 확인을 위해 "지정된 기간 동안 예약된 레코드 추출"
등을 원할 수 있습니다.

이 때, 레코드측의 예약 기간과 검색 조건의 날짜 기간을 합쳐서 원하는 것을 취득하게 됩니다.

먼저 결론



먼저 결론을 쓰면
where
    レコードの開始日付 <= 検索条件の終了日付
and レコードの終了日付 >= 検索条件の開始日付 

로 잡을 수 있습니다.

물론 사양에 따라 날짜뿐만 아니라 시간도 들어오기 때문에<= 또는 >= 대신 < 또는 > 또는 검색 기준의 날짜를 +1할 수 있습니다.

그리고 null가 얽혀 오는 경우는 그 대응도 필요합니다.

이번은 날짜 부분만의 단순 패턴입니다.

사고방식



데이터베이스 측의 테이블 데이터와 검색 조건의 관계를 고려하면
다음 패턴을 생각할 수 있습니다.


  • 검색 기간이 레코드 기간 이전
  • 검색 기간이 레코드 시작을 포함
  • 검색 기간이 레코드 기간에 포함됨
  • 검색 기간에는 레코드 종료가 포함됩니다
  • 검색 기간이 레코드 기간 이후
  • 검색 기간이 레코드 기간을 포함

  • 문장으로 설명을 써 보았습니다만 이미지로 파악하는 편이 알기 쉬울까 생각합니다.

    이 중 기간의 중첩이 있는 것은 적색으로 표시된 부분이 됩니다.

    녹색 부분의 부정으로 취하러 가는 방법도 있을지도 모릅니다만, 이번은 보통으로 적색의 부분을 추출해 갑니다.

    레코드 종료일에 주목





    레코드 측의 종료일에 주목합니다.

    그러면 검색 기준의 시작 날짜가 모두 왼쪽 (즉 이전)에 있음을 알 수 있습니다.

    이것을 쿼리로 표현하면
    検索条件の開始日付 <= レコードの終了日付
    

    됩니다.

    왼쪽에 테이블 열을 쓰는 경우가 많기 때문에 왼쪽과 오른쪽을 바꿉니다.
    レコードの終了日付 >= 検索条件の開始日付
    

    로 둡니다.

    이것은 1이 불필요합니다.

    레코드 시작 날짜에 주목





    레코드 측의 시작일에 주목합니다.

    그러면 검색 조건의 종료 날짜는 모두 오른쪽(즉 이후)에 있는 것을 알 수 있습니다.

    이것을 쿼리로 표현하면
    レコードの開始日付 <= 検索条件の終了日付
    

    이것은 5가 불필요합니다.

    두 조건 모두 결합



    1, 5는 한쪽에만 존재하기 때문에 AND로 조합하면 범위가 겹칠 수 있습니다.

    실제로 시도해보십시오.



    실제로 시도해 보겠습니다.
    데이터베이스는 H2 Database를 사용했습니다.

    테이블



    이런 느낌의 BOOKING 테이블을 준비합니다.


    열 이름
    형명
    메모


    BOOKING_ID
    VARCHAR(6)
    기본 키

    START_DATE
    DATE
    not null

    END_DATE
    DATE
    not null

    create table BOOKING (
       BOOKING_ID  VARCHAR(6)
      ,START_DATE  DATE not null
      ,END_DATE    DATE not null
      ,constraint PK_BOOKING primary key (
        BOOKING_ID
      )
    );
    

    데이터는 1건만 준비합니다.
    검색 조건을 다양하게 변경하여 확인해 보겠습니다.


    BOOKING_ID
    START_DATE
    END_DATE


    000001
    2021-01-01
    2021-01-31

    insert into BOOKING values ('000001', DATE'2021-01-01', DATE'2021-01-31');
    

    실행



    다음과 같은 쿼리를 실행해 봅니다.with를 사용하고 있기 때문에 이해하기 어렵습니다.
    SEARCH_CONDITION 측이 아닌 겹치는 검색 조건을 결과에 표시하도록 하고 있습니다.
    with
      -- 変化させる検索条件を6パターン用意
      SEARCH_CONDITION(SEARCH_ID, SEARCH_FROM, SEARCH_TO) as (
        select 1, '2020-12-01', '2020-12-31' union all
        select 2, '2020-12-15', '2021-01-15' union all
        select 3, '2021-01-10', '2021-01-20' union all
        select 4, '2021-01-15', '2021-02-15' union all
        select 5, '2021-02-15', '2021-02-28' union all
        select 6, '2020-12-01', '2021-02-28'
    )
    select
       C.SEARCH_ID
      ,C.SEARCH_FROM
      ,C.SEARCH_TO
    from
      BOOKING B
    cross join
      SEARCH_CONDITION C
    where
        B.START_DATE <= TO_DATE(C.SEARCH_TO, 'YYYY-MM-DD')
    and B.END_DATE   >= TO_DATE(C.SEARCH_FROM, 'YYYY-MM-DD')
    order by
      C.SEARCH_ID
    

    검색결과


    SEARCH_ID
    SEARCH_FROM
    SEARCH_TO


    2
    2020-12-15
    2021-01-15

    3
    2021-01-10
    2021-01-20

    4
    2021-01-15
    2021-02-15

    6
    2020-12-01
    2021-02-28


    2, 3, 4, 6이 결과에 오르고 있기 때문에 올바르게 체크할 수 있는 것을 확인할 수 있었습니다.

    좋은 웹페이지 즐겨찾기