2018-07-11
예약 시스템을 구현할때 꼭 들어가야 하는 기능이 중복체크이다.
이게, 단순히 하나의 시간대이면 편하지만, 예약기간이 1시~3시같은 시작과 종료가 있으면 쿼리가 조금 복잡해 진다.

그런데 최근 이런 이슈를 다루다가, 상당히 간편하고 좋은 쿼리를 찾아내서 이렇게 포스팅을 한다.
링크: http://www.gurubee.net/article/50256

위 글의 핵심은 아래와 같다
SELECT count(*) cnt FROM `table` WHERE `start` < :end AND `end` > :start
위 쿼리만 적용하면 중복 여부를 한번에 알아낼 수 있다.




삭제 대비용 원본글 복사



-- cnt가 0 이면 정상 1 이면 중복 --
SELECT COUNT(*) cnt
FROM 테이블
WHERE fr_time < :v_to_time
AND to_time > :v_fr_time
AND ROWNUM = 1
;



흔히들 기간 중복 체크 문제에서 복잡한 쿼리를 사용하는 경우가 많은데요.
중복 가능한 각각의 케이스를 조건으로 만들어 Or로 연결하는 방법이죠.
다음 6가지 케이스로 분류할 수 있겠는데요.
1. 시작 ~ 종료 안에 :시작, :종료가 포함되는 경우
2. 시작 ~ 종료 안에 :시작이 포함되는 경우
3. 시작 ~ 종료 안에 :종료가 포함되는 경우
4. 시작 ~ 종료 를 :시작, :종료가 포함하는 경우
5. 시작 ~ 종료 앞에 :시작, :종료가 있는 경우
6. 시작 ~ 종료 뒤에 :시작, :종료가 있는 경우
1~4번 케이스가 중복이 되는 경우죠.

하지만 위 4가지 조건은 잘 따지고 보면 결국 하나로 압축됩니다.
7. 시작이 :종료보다 작고 종료는 :시작보다 큰 경우
위 1~4번 조건에 7번 조건을 각각 대입해보면 잘 맞아 떨어진다는 것을 알 수 있습니다.
조건이 너무나도 단순하여 오히려 믿질 않는 사람이 많더군요.
하지만 이 조건은 너무나도 단순하면서도 강력한 조건입니다.

다음은 기간검색 관련해서 제가 일전에 냈었던 퀴즈입니다.
http://www.gurubee.net/article/45391