KEEP(DENSE_RANK FIRST(LAST)) 질문입니다. 0 5 2,437

by 빛나는관 [2015.07.02 18:43:38]


구루비 질문.PNG (7,408Bytes)

첫 번째 사진에서 볼 수 있듯이 부서번호가 20인 사원들 중에서 최대 월급인 사원이 두 명 존재하는데요,

KEEP(DENSE_RANK FIRST(LAST))함수를 이용하여 부서별 최대 및 최소 월급과 사원이름을 뽑으면

한 명만 나오는데, 왜 그런 건가요? 두 명이 다 나오게 할 수는 없을까요?!

by 마농 [2015.07.02 19:14:28]

집계함수란게 원래 여러행을 하나로 집계하는 거죠.
KEEP 에 의한 정렬결과 1등이 두명이 나온뒤에..
앞에 사용한 집계함수 MAX 에 의해서 둘 중 큰값이 나온 것이죠.
만약 MAX 대신 MIN 을 썼다면 작은 값이 나오겟죠.
그렇다면... MAX 나 MIN 대신 다른집계함수를 사용한다면?
 

SELECT deptno
     , MAX(sal) max_sal
     , wm_concat(ename) KEEP(DENSE_RANK LAST  ORDER BY sal) max_ename
     , MIN(sal) min_sal
     , wm_concat(ename) KEEP(DENSE_RANK FIRST ORDER BY sal) min_ename
  FROM emp
 GROUP BY deptno
 ORDER BY deptno
;

 


by 빛나는관 [2015.07.02 19:41:21]

마농님, 답변 감사합니다. 제가 MAX(ENAME)을 미처 생각하지 못 했었습니다.

그런데 WM_CONCAT이 지원되지 않는 함수라고 나오는데요 11g 에서는 사용이 안 되는 건가요?

올려주신 답변의 출력값을 알고 싶은데 안 되는군요 ㅠㅠ


by 창조의날개 [2015.07.02 19:19:38]

WITH EMP(DEPTNO, ENAME, SAL) AS(
    SELECT 10, 'KING', 5000 FROM DUAL UNION ALL
    SELECT 10, 'CLARK', 2450 FROM DUAL UNION ALL
    SELECT 10, 'MILLER', 1300 FROM DUAL UNION ALL
    SELECT 20, 'SCOTT', 3000 FROM DUAL UNION ALL
    SELECT 20, 'FORD', 3000 FROM DUAL UNION ALL
    SELECT 20, 'JONES', 2975 FROM DUAL UNION ALL
    SELECT 20, 'ADAMS', 1100 FROM DUAL UNION ALL
    SELECT 20, 'SMITH', 800 FROM DUAL UNION ALL
    SELECT 30, 'BLAKE', 2850 FROM DUAL UNION ALL
    SELECT 30, 'ALLEN', 1600 FROM DUAL UNION ALL
    SELECT 30, 'TURNER', 1500 FROM DUAL UNION ALL
    SELECT 30, 'MARTIN', 1250 FROM DUAL UNION ALL
    SELECT 30, 'WARD', 1250 FROM DUAL UNION ALL
    SELECT 30, 'JAMES', 950 FROM DUAL
)
, TT AS (
    SELECT DEPTNO
          , ENAME
          , SAL
          , DENSE_RANK() OVER(PARTITION BY DEPTNO ORDER BY SAL DESC) FIRST_RANK
          , DENSE_RANK() OVER(PARTITION BY DEPTNO ORDER BY SAL) LAST_RANK
    FROM EMP
)
SELECT T1.DEPTNO
     , T1.SAL   MAX_SAL
     , T1.ENAME MAX_ENAME
     , T2.SAL   MIN_SAL
     , T2.ENAME MIN_ENAME
FROM (
      SELECT DEPTNO, ENAME, SAL
      FROM TT
      WHERE FIRST_RANK = 1
      ) T1
    , (
      SELECT DEPTNO, ENAME, SAL
      FROM TT
      WHERE LAST_RANK = 1
      ) T2
WHERE T1.DEPTNO = T2.DEPTNO
ORDER BY DEPTNO
;

 


by 빛나는관 [2015.07.02 19:42:21]

창조의날개님, 정성스런 답변 감사합니다!!


by 마농 [2015.07.03 11:18:11]

wm_concat 는 10g 부터 사용가능하며 공식지원함수는 아닙니다.
안되는 이유는 글쎄요? 스텐다드에서는 안되는 것일까요?
실행결과는 다음과 같습니다. 'SCOTT,FORD'
참고 : Group By 에서 문자열 합치기 - 버전별 정리

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