<과제1> 현업이 요청한 레이아웃으로 아래와 같이 최종 결과를 추출하는 sql 작성
EMP_NO | EMP_NM | EMP_ GENDER |
COUPLE_YN | SPOUSE_NM | CHILD _NM |
CHILD_ GENDER |
CHILD_BIRTH_YMD | CHILD_AGE | TWIN_YN |
직원번호 | 직원성명 | 직원성별 | 사내부부여부 | 배우자 이름 |
자녀이름 | 자녀성별 | 자녀 생년월일 |
자녀나이 | 쌍생아 여부 |
상세요건
[1] 현재 재직 중인 임직원 중 자녀가 1명 이상인 사람
[2] 자녀의 생년월일이 2012년 1월 1일 ~ 2015년 12월 31일 경우만 대상에 포함
[3] 사내부부이면서 [1],[2] 조건에 만족하는 경우 자녀의 아버지 “직원번호” 기준으로 데이터 추출하고, 어머니는 리스트에서 제거할 것, 이 때 사내부부 여부는 Y로 표시, 배우자성명은 어머니 기준으로 표시
[4] 쌍생아의 경우 2명 모두 지원이 아님, 따라서 쌍생아 중 1명만 포함 시킬 것
[5] 쌍생아 1명을 가져오는 조건은 이름의 오름차순의 상위자로 추출할 것
풀이과정
: WITH문으로 자녀정보를 담은 테이블과, 사내부부 테이블을 따로 만들어
각 테이블을 EMP_C에 조인해서 최종 쿼리를 만드는 방법으로 생각.
CHILD 테이블
- FAM_C 테이블에서 2012년 1월 1일 ~ 2015년 12월 31일 사이에 태어난 자녀(A27) 정보만 담은 테이블
- 쌍생아의 경우 1명만 포함, 1명의 기준은 쌍생아 이름의 오름차순 상위자가 자녀이름에 들어감
SELECT ch.emp_no emp_no
, ch.fam_nm fam_nm
, ch.rel_type_cd
, ch.gender_cd gender_cd
, ch.birth_ymd birth_ymd
, tw.emp_no twin_emp_no
, tw.twin twin_nm
FROM (SELECT *
FROM FAM_C
WHERE rel_type_cd = 'A27'
AND birth_ymd BETWEEN '20120101' AND '20151231')ch
LEFT JOIN
(SELECT FAM1.EMP_NO AS emp_no
, FAM1.FAM_NM AS twin
FROM FAM_C FAM1
INNER JOIN FAM_C FAM2
ON FAM1.EMP_NO = FAM2.EMP_NO
AND FAM1.FAM_NM <> FAM2.FAM_NM
AND FAM1.REL_TYPE_CD = FAM2.REL_TYPE_CD
AND FAM1.REL_TYPE_CD = 'A27'
AND FAM1.BIRTH_YMD = FAM2.BIRTH_YMD) tw
ON ch.emp_no = tw.emp_no
WHERE ch.fam_nm <> tw.twin
AND fam_nm < tw.twin
OR tw.twin IS NULL;
쿼리결과
COUPLE 테이블
- FAM_REL_C 테이블과 EMP_C테이블로 현재 재직중인 사내부부 중 남편의 정보만 담은 테이블
- 배우자의 성명 컬럼추가
SELECT hus.emp_no AS h_no
, hus.emp_nm AS h_nm
, e2.emp_nm AS w_nm
FROM
(SELECT e1.emp_no AS emp_no
, e1.emp_nm AS emp_nm
, frel.emp_rel_no AS emp_rel_no
FROM fam_rel_c frel
LEFT JOIN emp_c e1 ON e1.emp_no = frel.emp_no
WHERE SYSDATE BETWEEN frel.sta_ymd AND frel.end_ymd
AND SYSDATE BETWEEN e1.hire_ymd AND e1.retire_ymd
AND rel_type_cd = 'A18') hus
LEFT JOIN emp_c e2 ON e2.emp_no = hus.emp_rel_no;
쿼리 결과
최종 쿼리
- 사내부부여부, 쌍생아 여부 CASE 조건문 이용
- 자녀 나이는 현재날짜 기준 만나이로 계산
- '현재 재직중' WHERE 조건문 이용
SELECT em.emp_no AS 직원번호
, em.emp_nm AS 직원성명
, em.gender_cd AS 직원성별
, (CASE WHEN co.h_no IS NULL THEN 'N' ELSE 'Y' END) AS 사내부부여부
, co.w_nm AS 배우자성명
, ch.fam_nm AS 자녀성명
, ch.gender_cd AS 자녀성별
, ch.birth_ymd AS 자녀생년월일
, FLOOR((TO_CHAR(SYSDATE, 'YYYYMMDD') - ch.birth_ymd)/10000) AS 자녀나이
,(CASE WHEN ch.twin_nm IS NULL THEN 'N' ELSE 'Y' END) AS 쌍생아여부
FROM emp_c em
INNER JOIN child ch ON em.emp_no = ch.emp_no
LEFT JOIN couple co ON em.emp_no = co.h_no
WHERE SYSDATE BETWEEN em.hire_ymd AND em.retire_ymd
ORDER BY em.emp_no;
WITH문 포함
WITH couple AS(
SELECT hus.emp_no AS h_no
, hus.emp_nm AS h_nm
, e2.emp_nm AS w_nm
FROM
(SELECT e1.emp_no AS emp_no
, e1.emp_nm AS emp_nm
, frel.emp_rel_no AS emp_rel_no
FROM fam_rel_c frel
LEFT JOIN emp_c e1 ON e1.emp_no = frel.emp_no
WHERE SYSDATE BETWEEN frel.sta_ymd AND frel.end_ymd
AND SYSDATE BETWEEN e1.hire_ymd AND e1.retire_ymd
AND rel_type_cd = 'A18') hus
LEFT JOIN emp_c e2 ON e2.emp_no = hus.emp_rel_no)
, child AS (
SELECT ch.emp_no emp_no
, ch.fam_nm fam_nm
, ch.rel_type_cd
, ch.gender_cd gender_cd
, ch.birth_ymd birth_ymd
, tw.emp_no twin_emp_no
, tw.twin twin_nm
FROM (SELECT *
FROM FAM_C
WHERE rel_type_cd = 'A27'
AND birth_ymd BETWEEN '20120101' AND '20151231')ch
LEFT JOIN
(SELECT FAM1.EMP_NO AS emp_no
, FAM1.FAM_NM AS twin
FROM FAM_C FAM1
INNER JOIN FAM_C FAM2
ON FAM1.EMP_NO = FAM2.EMP_NO
AND FAM1.FAM_NM <> FAM2.FAM_NM
AND FAM1.REL_TYPE_CD = FAM2.REL_TYPE_CD
AND FAM1.REL_TYPE_CD = 'A27'
AND FAM1.BIRTH_YMD = FAM2.BIRTH_YMD) tw
ON ch.emp_no = tw.emp_no
WHERE ch.fam_nm <> tw.twin
AND fam_nm < tw.twin
OR tw.twin IS NULL
)
SELECT em.emp_no AS 직원번호
, em.emp_nm AS 직원성명
, em.gender_cd AS 직원성별
, (CASE WHEN co.h_no IS NULL THEN 'N' ELSE 'Y' END) AS 사내부부여부
, co.w_nm AS 배우자성명
, ch.fam_nm AS 자녀성명
, ch.gender_cd AS 자녀성별
, ch.birth_ymd AS 자녀생년월일
, FLOOR((TO_CHAR(SYSDATE, 'YYYYMMDD') - ch.birth_ymd)/10000) AS 자녀나이
,(CASE WHEN ch.twin_nm IS NULL THEN 'N' ELSE 'Y' END) AS 쌍생아여부
FROM emp_c em
INNER JOIN child ch ON em.emp_no = ch.emp_no
LEFT JOIN couple co ON em.emp_no = co.h_no
WHERE SYSDATE BETWEEN em.hire_ymd AND em.retire_ymd
ORDER BY em.emp_no;
쿼리결과
<과제2> LISTAGG를 활용하여 직원번호가 10001483 인 자녀의 성명이 한줄로 추출 되도록 SQL작성
SELECT EMP_NO AS 직원번호,
LISTAGG(FAM_NM, ',') WITHIN GROUP(ORDER BY FAM_NM) AS 자녀성명
FROM FAM_C
WHERE EMP_NO = '10001483'
AND REL_TYPE_CD = 'A27'
GROUP BY EMP_NO;
쿼리결과
'교육 및 공부' 카테고리의 다른 글
[데이터리안] SQL 데이터분석 캠프 - 입문반 솔직후기 (+5만원환급이벤트) (0) | 2022.06.15 |
---|---|
[코멘토 SQL직무부트캠프] 3차과제-SQL 실무 연습 (0) | 2022.06.11 |
[코멘토 SQL직무부트캠프] 2차 과제-데이터추출요청서&SQL연습 (0) | 2022.06.03 |
[코멘토 SQL직무부트 캠프] 1차과제-데이터 탐색(오라클) (0) | 2022.06.03 |