[SQL 쿡북/09장] 13절. 중복 날짜 범위 식별하기

정은아·2025년 5월 23일

[도서] SQL 쿡북

목록 보기
12/13
post-thumbnail

09장. 날짜 조작기법


🎨 DB2, PostgreSQL, Oracle

SELECT a.empno, 
       a.ename,
       'project ' || b.proj_id || 
       ' overlaps project ' || a.proj_id msg
FROM emp_project a,
     emp_project b
WHERE a.empno = b.empno
  AND b.proj_start >= a.proj_start
  AND b.proj_start <= a.proj_end
  AND a.proj_id != b.proj_id;

✅ 해석

  1. FROM emp_project a, emp_project b

    • emp_project 테이블을 두 번 사용하여
      같은 직원(empno)의 프로젝트 쌍을 모두 생성
  2. WHERE a.empno = b.empno

    • 동일한 직원의 프로젝트끼리만 비교
  3. AND b.proj_start >= a.proj_start

  4. AND b.proj_start <= a.proj_end

    • b의 프로젝트 시작일이
      a 프로젝트 기간 안에 포함되는 경우를 확인
    • 즉, 날짜가 겹침(overlaps)
  5. AND a.proj_id != b.proj_id

    • 동일 프로젝트끼리 비교하지 않기 위한 조건
      자기 자신은 제외
  6. SELECT ... || ' overlaps ...'

    • 조건을 만족하는 프로젝트 쌍에 대해
      "project B overlaps project A" 형태의 메시지를 생성하여 출력

✅ 예시 결과

empnoenamemsg
7788SCOTTproject B overlaps project A
7788SCOTTproject C overlaps project B

🎨 MySQL

  • EMP_PROJECT에 셀프 조인합니다.
  • 그런 다음 CONCAT 함수를 사용하여 겹치는 프로젝트를 설명하는 메시지를 구성합니다.
SELECT a.empno, a.ename,
       CONCAT('project ', b.proj_id,
              ' overlaps project ', a.proj_id) AS msg
FROM emp_project a,
     emp_project b
WHERE a.empno = b.empno
  AND b.proj_start >= a.proj_start
  AND b.proj_start <= a.proj_end
  AND a.proj_id != b.proj_id;

✅ 해석

  1. FROM emp_project a, emp_project b

    • emp_project 테이블을 두 번 사용하여
      동일 직원(empno)의 프로젝트 쌍(a, b) 을 비교
  2. WHERE a.empno = b.empno

    • 같은 직원의 프로젝트끼리만 비교 대상이 됨
  3. AND b.proj_start >= a.proj_start

  4. AND b.proj_start <= a.proj_end

    • b 프로젝트의 시작일이
      a 프로젝트의 시작일과 종료일 사이에 포함되면
    • 두 프로젝트의 기간이 겹친다(overlap)
  5. AND a.proj_id != b.proj_id

    • 동일한 프로젝트끼리 비교하는 것을 제외
      → 자기 자신과의 비교 방지
  6. SELECT ... CONCAT(...) AS msg

    • 조건을 만족하는 프로젝트 쌍에 대해
      "project B overlaps project A" 형태의 메시지를 생성

✅ 예시 출력

empnoenamemsg
7788SCOTTproject B overlaps project A
7788SCOTTproject C overlaps project B

🎨 SQL Server

SELECT a.empno, a.ename,
       'project ' + b.proj_id +
       ' overlaps project ' + a.proj_id AS msg
FROM emp_project a,
     emp_project b
WHERE a.empno = b.empno
  AND b.proj_start >= a.proj_start
  AND b.proj_start <= a.proj_end
  AND a.proj_id != b.proj_id;

✅ 해석

  1. FROM emp_project a, emp_project b

    • emp_project 테이블을 두 번 사용하여
      같은 직원(empno)의 프로젝트 쌍을 비교할 준비를 함
  2. WHERE a.empno = b.empno

    • 비교하는 두 프로젝트가 동일 직원의 것인지 확인
  3. AND b.proj_start >= a.proj_start

  4. AND b.proj_start <= a.proj_end

    • b 프로젝트의 시작일이
      a 프로젝트의 시작일과 종료일 사이에 포함되는 경우
    • 즉, 두 프로젝트 간에 기간이 겹침(overlap)
  5. AND a.proj_id != b.proj_id

    • 자기 자신과의 비교를 방지
      → 동일한 프로젝트는 비교 대상에서 제외
  6. SELECT ... AS msg

    • 문자열을 연결하여 메시지 생성
      예: 'project B overlaps project A'

✅ 예시 결과

empnoenamemsg
7788SCOTTproject B overlaps project A
7788SCOTTproject C overlaps project B
profile
꾸준함의 가치를 믿는 개발자

0개의 댓글