근무한 직원이 없어도 직종은 보이게 하고싶어요! 1 12 1,907

by DONKEY [SQL Query] [2016.09.12 11:34:39]


쿼리결과.PNG (25,940Bytes)
인사테이블.PNG (49,802Bytes)
발령테이블.PNG (57,195Bytes)
간호부부서.PNG (50,786Bytes)

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병동처럼 간호사,조무원,간호조무사 순으로 나오게하는 것입니다!

by jkson [2016.09.12 12:18:39]

밥먹기 직전이라 쿼리 분석은 안 될 것 같고.. ㅋ

아래 '조회결과에서 공통 항목을 추가하고 싶습니다.' 와 비슷한 질문이신 것 같네요.

마농님 답변 참조해보세요. 맛점하세요~


by DONKEY [2016.09.12 13:51:28]

맛점 하셨나요?? 질문 하나만 드리겠습니다..ㅜ PARTITION OUTER JOIN으로 해결 해야되는 문제 같은데..제가 어떤식으로 적용해야될지 잘 모르겠네요.. 현제 쿼리는 오라클 조인으로 작성 되어있고 PARTITION OUTER JOIN은 ANSI 표준으로만 사용할 수 있다는데 혹 대~충이라도 가이드해주실수 있으실까요 ㅜㅜ? 죄송합니다..


by jkson [2016.09.12 17:06:19]
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

이렇게 해보세요.


by DONKEY [2016.09.12 17:17:01]

바쁘신데 답변 정말 감사드립니다..ㅠㅠ 하루종일 여기붙이고 저기붙이고 해도 안되서 막막하네요.. 작성해주신 코드 적용 해봤는데 병동에서 근무를 하지 않은 직종에 대해서는 조회가 안되는걸로 확인했습니다.. 


by jkson [2016.09.12 17:36:52]

결과만 놓고 보면 나와야할 것 같은데 이상하네요.

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의 컬럼 값으로 해야 나오겠죠.

위에 수정된 쿼리로 돌려보세요.


by DONKEY [2016.09.12 17:50:15]

제가 쿼리를 잘못 짠게 아닌가 생각이 드네요..실행결과는 똑같습니다..ㅠㅠ 바쁘신 시간 쪼개 답변해주셔 정말 감사드립니다 ..ㅜㅜ 


by DONKEY [2016.09.12 13:03:42]

감사합니닷 참고해서 차근차근 작성해보도록 하겠습니다.


by DONKEY [2016.09.12 19:13:33]

JKSON님!.. 찾아냈습니다.. 혹시나 보실까해서 글 남겨놓겠습니다.. WHERE '20150815' BETWEEN FR_YMD AND TO_YMD <<이부분이 말썽이었네요.. 저조건에 만족 못해 아무리 외부조인을 걸어도 MISSING VALUE가 체워지지 않았던거 같습니다! 감사하고 죄송합니다!


by 마농 [2016.09.13 08:37:16]

원본 쿼리에 문제가 많아 보입니다.
최종 사용하지도 않는 값들에 대해 너무 복잡하게 쿼리하고 있네요.
조건절도 이상하여 카티션 프러덕이 발생할 것 같구요.
원하시는 결과를 얻기 위해 이렇게 복잡한 쿼리가 필요하지 않을 듯 하네요.
간단하게 원본 테이블과 결과테이블만 보여주시면 좋겠네요.


by DONKEY [2016.09.13 15:40:58]

원본테이블은 MIJ_ANNOUNCE 발령 테이블 MIJ_EMPLOYE 인사 MST OCS.ZMM_COM_CD 간호부 부서를 가져오는 공통 테이블로 구성되어 있으며

MIJ_ANNOUNCE 테이블에서는 조회 기준일을 기준으로 그때당시에 해당부서에서 근무했던 간호사,조무사,조무원을 가지고 옵니다. 발령테이블에서 가져온 근무자들과 공통 테이블과 조인하여 부서별 근무자들의 성명과 인원수를 세는 쿼리입니다! 발령 테이블에서 발령 시작일은 정확하게 들어와 있는데 발령 종료일이 좀 이상한상태입니다..(발령 시작일과 동일하게 발령종료일이 세팅되어있습니다.)

조회 결과는 본문 제일 아래 그림이구요 부서에 직종별인원이 아우터된 상태로 조회하고 싶습니다.


by 마농 [2016.09.13 16:32:20]
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
;

 


by DONKEY [2016.09.13 16:44:02]

감사합니다 ㅠㅠ 직종 리스트 만드는 첫번째 서브쿼리에 = --->> IN으로 바꾸고 나니 잘실행됩니다!! 열공 열일 하겠습니다 배운걸 기반으로!

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입