[SQL 쿡북/09장] 12절. 날짜의 특정 부분을 레코드 비교하기

정은아·2025년 5월 23일

[도서] SQL 쿡북

목록 보기
11/13
post-thumbnail

09장. 날짜 조작기법


  • 한 사원의 HIREDATE를 다른 사원의 HIREDATE와 비교하려면 EMP 테이블에 셀프 조인해야 합니다.
  • 이를 통해 HIREDATE의 가능한 조합을 비교할 수 있습니다.
  • 그런 다음 HIREDATE에서 요일과 월을 추출하고 비교합니다.

🎨 DB2

  • EMP 테이블을 셀프 조인한 뒤에 DAYOFWEEK 함수를 사용하여 요일 숫자를 반환합니다.
  • MONTHNAME 함수를 사용하여 우러 이름을 반환합니다.
SELECT a.ename || 
       ' was hired on the same month and weekday as ' || 
       b.ename msg
FROM emp a, emp b
WHERE (DAYOFWEEK(a.hiredate), MONTHNAME(a.hiredate)) = 
      (DAYOFWEEK(b.hiredate), MONTHNAME(b.hiredate))
  AND a.empno < b.empno
ORDER BY a.ename;

✅ 해석

  1. FROM emp a, emp b

    • emp 테이블을 두 번 조회하여 모든 직원 쌍(a, b) 을 생성
    • → 자기 자신과 다른 직원들을 비교 가능한 구조로 만듦
  2. WHERE (...) = (...)

    • 두 직원 a, b의 다음 두 값이 같을 때만 필터링:
      1. DAYOFWEEK(hiredate)입사 요일 (1: Sunday ~ 7: Saturday)
      2. MONTHNAME(hiredate)입사 월 이름 (예: 'February')
    • ✅ 즉, 입사 요일과 입사 월이 동일한 직원 쌍만 추출
  3. AND a.empno < b.empno

    • 동일한 쌍의 중복 제거를 위한 조건
      • 예: (a=SMITH, b=JONES)만 남기고 (b=JONES, a=SMITH)는 제거
  4. SELECT a.ename || ' was hired on the same ...'

    • 조건을 만족하는 직원 쌍에 대해 메시지를 생성
    • "SMITH was hired on the same weekday and month as JONES" 형태의 결과
  5. ORDER BY a.ename

    • 첫 번째 사원의 이름(a.ename) 기준으로 오름차순 정렬

🎨 Oracle과 PostgreSQL

  • EMP 테이블을 셀프 조인한 뒤에 TO_CHAR함수를 사용하여 비교를 위해 HIREDATE를 요일 및 월로 지정합니다.
SELECT a.ename || 
       ' was hired on the same month and weekday as ' || 
       b.ename AS msg
FROM emp a, emp b
WHERE TO_CHAR(a.hiredate, 'DMon') = TO_CHAR(b.hiredate, 'DMon')
  AND a.empno < b.empno
ORDER BY a.ename;

✅ 해석

  1. FROM emp a, emp b

    • emp 테이블을 두 번 사용하여 모든 직원 간 쌍(a, b) 을 생성
    • → 모든 직원 조합을 비교할 수 있는 구조
  2. WHERE TO_CHAR(a.hiredate, 'DMon') = TO_CHAR(b.hiredate, 'DMon')

    • TO_CHAR(hiredate, 'DMon'):
      • 입사일의 요일(D)월(Mon)을 문자열로 반환
      • 예:
        • 월요일 2월 입사 → '2Feb'
        • 수요일 12월 입사 → '4Dec'
    • ab의 입사일이 같은 요일 + 같은 달이면 조건 만족
  3. a.empno < b.empno

    • 중복된 쌍 제거를 위한 조건
      • 예: (ALLEN, SMITH)만 남기고 (SMITH, ALLEN)은 제거
  4. SELECT ... || ... || ... AS msg

    • a.enameb.ename을 연결해 한 줄 메시지로 출력
    • 예: "ALLEN was hired on the same weekday and month as SMITH"
  5. ORDER BY a.ename

    • 첫 번째 직원 a의 이름 기준으로 정렬

🎨 MySQL

  • EMP 테이블을 셀프 조인한 뒤에 DATE_FORMAT 함수를 사용하여 비교를 위해 HIREDATE를 요일 및 월로 지정합니다.
SELECT CONCAT(a.ename,
              ' was hired on the same month and weekday as ',
              b.ename) msg
FROM emp a, emp b
WHERE DATE_FORMAT(a.hiredate, '%W%M') = DATE_FORMAT(b.hiredate, '%W%M')
  AND a.empno < b.empno
ORDER BY a.ename;

✅ 해석

  1. FROM emp a, emp b

    • emp 테이블을 두 번 사용하여 모든 사원 쌍(a, b) 을 생성
    • → 모든 사원 간의 비교를 수행할 수 있도록 함
  2. WHERE DATE_FORMAT(...) = DATE_FORMAT(...)

    • DATE_FORMAT(hiredate, '%W%M'):
      • 입사일의 요일명(%W) + 월명(%M)을 문자열로 반환
      • 예:
        • 2024-02-13 (화요일) → 'TuesdayFebruary'
        • 2024-12-09 (월요일) → 'MondayDecember'
    • → 두 사원의 입사일이 같은 요일 + 같은 월이면 조건 만족
  3. AND a.empno < b.empno

    • 중복 쌍 제거를 위한 조건
      • 예: (a=ALLEN, b=SMITH)는 남기고 (b=SMITH, a=ALLEN)은 제외
  4. SELECT CONCAT(...) AS msg

    • "a.ename was hired on the same month and weekday as b.ename"
      형태로 두 사원의 이름을 포함한 문장을 생성하여 출력
  5. ORDER BY a.ename

    • 기준 사원인 a.ename 기준으로 결과를 오름차순 정렬

🎨 SQL Server

  • EMP 테이블을 셀프 조인한 뒤에 DATE_FORMAT 함수를 사용하여 비교를 위해 HIREDATE를 요일 및 월로 지정합니다.
SELECT a.ename + 
       ' was hired on the same month and weekday as ' + 
       b.ename msg
FROM emp a, emp b
WHERE DATENAME(dw, a.hiredate) = DATENAME(dw, b.hiredate)
  AND DATENAME(m, a.hiredate) = DATENAME(m, b.hiredate)
  AND a.empno < b.empno
ORDER BY a.ename;

✅ 해석

  1. FROM emp a, emp b

    • emp 테이블을 두 번 사용하여 직원 간 모든 쌍(a, b) 을 생성
    • 자기 자신 포함한 모든 조합을 비교 가능
  2. WHERE DATENAME(...) = DATENAME(...)

    • DATENAME(dw, a.hiredate) = DATENAME(dw, b.hiredate)
      → 두 직원의 입사 요일 이름이 같아야 함
      예: 'Monday', 'Tuesday', 'Friday'

    • DATENAME(m, a.hiredate) = DATENAME(m, b.hiredate)
      → 두 직원의 입사 월 이름이 같아야 함
      예: 'February', 'December', 'June'

    • a.empno < b.empno
      → 동일한 쌍의 중복 제거
      (a, b)는 포함하고 (b, a)는 제거
      자기 자신과의 비교도 방지

  3. SELECT ... + ... + ... AS msg

    • 두 직원의 이름을 문자열로 연결하여 문장 형태로 출력
    • 예:
      ALLEN was hired on the same month and weekday as SMITH
  4. ORDER BY a.ename

    • 기준 직원 a의 이름을 기준으로 정렬
profile
꾸준함의 가치를 믿는 개발자

0개의 댓글