WITH EMP_ANNOUNCE AS
(SELECT A.EMP_NO, A.ORD_FR_YMD, A.SEQ, A.DUT_DEPT_CD,A.OCP_TYPE_CD, ROW_NUMBER() OVER (ORDER BY A.EMP_NO, A.ORD_FR_YMD, A.SEQ) AS RN
FROM MIJ_ANNOUNCE A LEFT JOIN MIJ_ANNOUNCE B
ON A.EMP_NO = B.EMP_NO
AND B.ORD_FR_YMD||B.SEQ = (SELECT MAX(X.ORD_FR_YMD||X.SEQ)
FROM MIJ_ANNOUNCE X
WHERE A.EMP_NO = X.EMP_NO
AND X.ORD_FR_YMD||X.SEQ < A.ORD_FR_YMD||A.SEQ )
WHERE A.DUT_DEPT_CD <> NVL(B.DUT_DEPT_CD,'@')
)
,EMP_DEPT_HIST AS
(SELECT KOR_NM
,EMP_NO
,DUT_DEPT_NM
,FR_YMD
,TO_YMD
,DUT_DEPT_CD
,SUB_VAL3
,SORT_NO
,OCP_TYPE_CD
FROM (SELECT C.KOR_NM
, A.EMP_NO
, E.COM_NM AS DUT_DEPT_NM
, A.ORD_FR_YMD AS FR_YMD
, TO_CHAR(TO_DATE(NVL(B.ORD_FR_YMD, NVL(C.RTMT_YMD, '29991231')), 'YYYYMMDD') -1, 'YYYYMMDD') AS TO_YMD
, A.DUT_DEPT_CD
, E.SUB_VAL3
, E.SORT_NO
, A.OCP_TYPE_CD
FROM EMP_ANNOUNCE A
, EMP_ANNOUNCE B
, MIJ_EMPLOYE C
, OCS.ZMM_COM_CD E
WHERE A.EMP_NO = B.EMP_NO(+)
AND A.RN = B.RN(+) - 1
AND A.EMP_NO = C.EMP_NO
AND C.RTMT_YMD IS NULL
AND A.DUT_DEPT_CD = E.COM_CD
AND E.DIV_CD = 'NUR_DEPT_GB'
AND A.OCP_TYPE_CD IN ('022','081','076')
)
)SELECT DUT_DEPT_NM
, SORT_NO
, OCP_TYPE_CD
, (SELECT COM_NM
FROM OCS.ZMM_COM_CD
WHERE DIV_CD = 'OCP_TYPE_CD'
AND COM_CD = OCP_TYPE_CD) AS OCP_TYPE_NM
, DECODE(OCP_TYPE_CD,'022',COUNT(*)
,'081',COUNT(*)
,'076',COUNT(*)) AS CNT
, DECODE(OCP_TYPE_CD,'022',LISTAGG(KOR_NM,'/') WITHIN GROUP (ORDER BY KOR_NM)
,'081',LISTAGG(KOR_NM,'/') WITHIN GROUP (ORDER BY KOR_NM)
,'076',LISTAGG(KOR_NM,'/') WITHIN GROUP (ORDER BY KOR_NM)) AS DUTY
FROM EMP_DEPT_HIST
WHERE '20150815' BETWEEN FR_YMD AND TO_YMD
GROUP BY DUT_DEPT_NM ,SORT_NO ,OCP_TYPE_CD
ORDER BY SORT_NO, OCP_TYPE_CD
안녕하십니까!
시원한 가을날씨네요 요즘..ㅋㅋㅋㅋ
날씨는 시원한데 쿼리는 시원하게 짜지지 않아 고민입니다!
오늘도 도움을 얻고자 글을 올리게 되었습니다!
쿼리는 위와 같으며 제가 원하는 쿼리결과는
해당 병동에서 근무한 인원이 없어도 일딴은 조회 되게끔 하고 싶습니다!
어떤식의 조인을 걸어야 제가 원하는 쿼리결과를 얻을 수 있을까요?
풀 아우터 조인을 해봤는데도 안나오네요.. 한수 부탁드리겠습니다..
지금 쿼리로 나오는 결과는 아래와 같습니다
11병동에 조무원으로 근무한 사람이 없어 조무원이 조회 결과로써 나오지 않는 상황입니다..
원하는 결과는 21병동처럼 간호사,조무원,간호조무사 순으로 나오게하는 것입니다!
밥먹기 직전이라 쿼리 분석은 안 될 것 같고.. ㅋ
아래 '조회결과에서 공통 항목을 추가하고 싶습니다.' 와 비슷한 질문이신 것 같네요.
마농님 답변 참조해보세요. 맛점하세요~
맛점 하셨나요?? 질문 하나만 드리겠습니다..ㅜ PARTITION OUTER JOIN으로 해결 해야되는 문제 같은데..제가 어떤식으로 적용해야될지 잘 모르겠네요.. 현제 쿼리는 오라클 조인으로 작성 되어있고 PARTITION OUTER JOIN은 ANSI 표준으로만 사용할 수 있다는데 혹 대~충이라도 가이드해주실수 있으실까요 ㅜㅜ? 죄송합니다..
SELECT DUT_DEPT_NM
, SORT_NO
, A.COM_CD OCP_TYPE_CD
, A.COM_NM OCP_TYPE_NM
, DECODE(OCP_TYPE_CD,'022',COUNT(*)
,'081',COUNT(*)
,'076',COUNT(*)) AS CNT
, DECODE(OCP_TYPE_CD,'022',LISTAGG(KOR_NM,'/') WITHIN GROUP (ORDER BY KOR_NM)
,'081',LISTAGG(KOR_NM,'/') WITHIN GROUP (ORDER BY KOR_NM)
,'076',LISTAGG(KOR_NM,'/') WITHIN GROUP (ORDER BY KOR_NM)) AS DUTY
FROM (SELECT COM_CD, COM_NM
FROM OCS.ZMM_COM_CD
WHERE DIV_CD = 'OCP_TYPE_CD'
AND COM_CD IN ('022','081','076')) A LEFT OUTER JOIN EMP_DEPT_HIST B
PARTITION BY (DUT_DEPT_NM)
ON (A.COM_CD = B.OCP_TYPE_CD)
WHERE '20150815' BETWEEN FR_YMD AND TO_YMD
GROUP BY DUT_DEPT_NM ,SORT_NO ,OCP_TYPE_CD
ORDER BY SORT_NO, OCP_TYPE_CD
이렇게 해보세요.
제가 쿼리를 잘못 짠게 아닌가 생각이 드네요..실행결과는 똑같습니다..ㅠㅠ 바쁘신 시간 쪼개 답변해주셔 정말 감사드립니다 ..ㅜㅜ
바쁘신데 답변 정말 감사드립니다..ㅠㅠ 하루종일 여기붙이고 저기붙이고 해도 안되서 막막하네요.. 작성해주신 코드 적용 해봤는데 병동에서 근무를 하지 않은 직종에 대해서는 조회가 안되는걸로 확인했습니다..
결과만 놓고 보면 나와야할 것 같은데 이상하네요.
LEFT OUTER JOIN 이므로 A에 있는 직종은 무조건 나와야 하는 것이고 PARTITION BY 에 DUT_DEPT_NM을 해주었으므로 DUT_DEPT_NM 도 나와야 하구요..
WITH T AS ( SELECT '11병동' AS DUT_DEPT_NM,'2' AS SORT_NO,'22' AS OCP_TYPE_CD,'간호사' AS OCP_TYPE_NM,'17' AS CNT FROM DUAL UNION ALL SELECT '11병동','2','81','간호조무사','2' FROM DUAL UNION ALL SELECT '21병동','3','22','간호사','16' FROM DUAL ) SELECT * FROM (SELECT '22' CODE, '간호사' FROM DUAL UNION ALL SELECT '81' CODE, '간호조무사' FROM DUAL UNION ALL SELECT '76' CODE, '조무원' FROM DUAL ) A LEFT OUTER JOIN T B PARTITION BY (DUT_DEPT_NM) ON (A.CODE = B.OCP_TYPE_CD)
이런 식으로요. 제가 뭔가 빠뜨린 건지..;
-------------------------------------------
SELECT 절을 그대로 써놨었네요. A의 컬럼 값으로 해야 나오겠죠.
위에 수정된 쿼리로 돌려보세요.
감사합니닷 참고해서 차근차근 작성해보도록 하겠습니다.
JKSON님!.. 찾아냈습니다.. 혹시나 보실까해서 글 남겨놓겠습니다.. WHERE '20150815' BETWEEN FR_YMD AND TO_YMD <<이부분이 말썽이었네요.. 저조건에 만족 못해 아무리 외부조인을 걸어도 MISSING VALUE가 체워지지 않았던거 같습니다! 감사하고 죄송합니다!
원본 쿼리에 문제가 많아 보입니다.
최종 사용하지도 않는 값들에 대해 너무 복잡하게 쿼리하고 있네요.
조건절도 이상하여 카티션 프러덕이 발생할 것 같구요.
원하시는 결과를 얻기 위해 이렇게 복잡한 쿼리가 필요하지 않을 듯 하네요.
간단하게 원본 테이블과 결과테이블만 보여주시면 좋겠네요.
원본테이블은 MIJ_ANNOUNCE 발령 테이블 MIJ_EMPLOYE 인사 MST OCS.ZMM_COM_CD 간호부 부서를 가져오는 공통 테이블로 구성되어 있으며
MIJ_ANNOUNCE 테이블에서는 조회 기준일을 기준으로 그때당시에 해당부서에서 근무했던 간호사,조무사,조무원을 가지고 옵니다. 발령테이블에서 가져온 근무자들과 공통 테이블과 조인하여 부서별 근무자들의 성명과 인원수를 세는 쿼리입니다! 발령 테이블에서 발령 시작일은 정확하게 들어와 있는데 발령 종료일이 좀 이상한상태입니다..(발령 시작일과 동일하게 발령종료일이 세팅되어있습니다.)
조회 결과는 본문 제일 아래 그림이구요 부서에 직종별인원이 아우터된 상태로 조회하고 싶습니다.
SELECT b.dut_dept_nm
, b.sort_no
, a.ocp_type_cd
, a.ocp_type_nm
, NVL(b.cnt, 0) cnt
, b.duty
FROM (SELECT com_cd ocp_type_cd
, com_nm ocp_type_nm
FROM ocs.zmm_com_cd
WHERE div_cd = 'OCP_TYPE_CD'
AND com_cd = ('022','081','076')
) a
LEFT OUTER JOIN
(SELECT a.dut_dept_cd
, e.com_nm dut_dept_nm
, e.sort_no
, a.ocp_type_cd
, COUNT(*) cnt
, LISTAGG(c.kor_nm, '/') WITHIN GROUP(ORDER BY c.kor_nm) duty
FROM (SELECT emp_no, ord_fr_ymd, seq, dut_dept_cd, ocp_type_cd
, ROW_NUMBER() OVER(PARTITION BY emp_no
ORDER BY ord_fr_ymd DESC, seq DESC) rn
FROM mij_announce
WHERE ord_fr_ymd <= '20150815'
) a
, mij_employe c
, ocs.zmm_com_cd e
WHERE a.rn = 1
AND a.ocp_type_cd IN ('022','081','076')
AND a.emp_no = c.emp_no
AND NVL(c.rtmt_ymd, '29991231') > '20150815'
AND a.dut_dept_cd = e.com_cd
AND e.div_cd = 'NUR_DEPT_GB'
GROUP BY a.dut_dept_cd, e.com_nm, e.sort_no, a.ocp_type_cd
) b
PARTITION BY (b.dut_dept_cd, b.dut_dept_nm, b.sort_no)
ON a.ocp_type_cd = b.ocp_type_cd
ORDER BY b.sort_no, a.ocp_type_cd
;
감사합니다 ㅠㅠ 직종 리스트 만드는 첫번째 서브쿼리에 = --->> IN으로 바꾸고 나니 잘실행됩니다!! 열공 열일 하겠습니다 배운걸 기반으로!