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이 결과에 오르고 있기 때문에 올바르게 체크할 수 있는 것을 확인할 수 있었습니다.
Reference
이 문제에 관하여(SQL에서 날짜 범위의 오버랩 확인), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/epsilon_87_myo/items/548ac99978caa2650850텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)