[퀴즈] 계층구조 쿼리의 이해 - 직상위자 이름 가져오기 0 9 7,323

by 마농 계층쿼리 prior [2010.02.09 16:17:43]



[퀴즈] 계층구조 쿼리의 이해 - 직상위자 이름 가져오기

사원번호, 성명, 상사 사원번호 를 가진 테이블 emp가 있습니다.
이 테이블의 자료를 다음과 같은 계층구조로 표현하세요.

WITH emp AS
(
SELECT 7369 empno, 'SMITH' ename, 7902 mgr FROM dual
UNION ALL SELECT 7499, 'ALLEN' , 7698 FROM dual
UNION ALL SELECT 7521, 'WARD'  , 7698 FROM dual
UNION ALL SELECT 7566, 'JONES' , 7839 FROM dual
UNION ALL SELECT 7654, 'MARTIN', 7698 FROM dual
UNION ALL SELECT 7698, 'BLAKE' , 7839 FROM dual
UNION ALL SELECT 7782, 'CLARK' , 7839 FROM dual
UNION ALL SELECT 7788, 'SCOTT' , 7566 FROM dual
UNION ALL SELECT 7839, 'KING'  , NULL FROM dual
UNION ALL SELECT 7844, 'TURNER', 7698 FROM dual
UNION ALL SELECT 7876, 'ADAMS' , 7788 FROM dual
UNION ALL SELECT 7900, 'JAMES' , 7698 FROM dual
UNION ALL SELECT 7902, 'FORD'  , 7566 FROM dual
UNION ALL SELECT 7934, 'MILLER', 7782 FROM dual
)
SELECT * FROM emp;

[원본] [결과]
EMPNO ENAME MGR EMPNO ENAME MGR LV MGR_ENAME
7369 SMITH 7902 7839 KING   1  
7499 ALLEN 7698 7566 -JONES 7839 2 KING
7521 WARD 7698 7788 --SCOTT 7566 3 JONES
7566 JONES 7839 7876 ---ADAMS 7788 4 SCOTT
7654 MARTIN 7698 7902 --FORD 7566 3 JONES
7698 BLAKE 7839 7369 ---SMITH 7902 4 FORD
7782 CLARK 7839 7698 -BLAKE 7839 2 KING
7788 SCOTT 7566 7499 --ALLEN 7698 3 BLAKE
7839 KING   7521 --WARD 7698 3 BLAKE
7844 TURNER 7698 7654 --MARTIN 7698 3 BLAKE
7876 ADAMS 7788 7844 --TURNER 7698 3 BLAKE
7900 JAMES 7698 7900 --JAMES 7698 3 BLAKE
7902 FORD 7566 7782 -CLARK 7839 2 KING
7934 MILLER 7782 7934 --MILLER 7782 3 CLARK


정답은 몇일뒤에 올리겠습니다.

[정답보기] <=== 트리플클릭
SELECT empno
, LPAD('-',LEVEL-1,'-') || ename ename
, mgr
, LEVEL lv
, PRIOR ename mgr_ename
  FROM emp
 START WITH mgr IS NULL
 CONNECT BY PRIOR empno = mgr
;

by Ejql [2010.02.09 16:47:58]
스칼라서브쿼리로 풀었습니다. 다른건 생각이 안나네요.
SELECT empno, lpad(ename,length(ename)+level -1,'-'), mgr, level LV , (select ename from emp b where b.empno = a.mgr) mgr_ename FROM emp a
start with empno = 7839
connect by prior empno = mgr

by 마농 [2010.02.10 09:30:08]
좀더 간단한 방법은 없을까요?

by 서성우 [2010.02.10 11:34:17]
오랜만에 들어왔는데 퀴즈가 있군요 ㅋㅋ

WITH emp AS
(
SELECT 7369 empno, 'SMITH' ename, 7902 mgr FROM dual
UNION ALL SELECT 7499, 'ALLEN' , 7698 FROM dual
UNION ALL SELECT 7521, 'WARD' , 7698 FROM dual
UNION ALL SELECT 7566, 'JONES' , 7839 FROM dual
UNION ALL SELECT 7654, 'MARTIN', 7698 FROM dual
UNION ALL SELECT 7698, 'BLAKE' , 7839 FROM dual
UNION ALL SELECT 7782, 'CLARK' , 7839 FROM dual
UNION ALL SELECT 7788, 'SCOTT' , 7566 FROM dual
UNION ALL SELECT 7839, 'KING' , NULL FROM dual
UNION ALL SELECT 7844, 'TURNER', 7698 FROM dual
UNION ALL SELECT 7876, 'ADAMS' , 7788 FROM dual
UNION ALL SELECT 7900, 'JAMES' , 7698 FROM dual
UNION ALL SELECT 7902, 'FORD' , 7566 FROM dual
UNION ALL SELECT 7934, 'MILLER', 7782 FROM dual
)
SELECT empno,
LPad(' ',level,'-')||ename ename,
mgr,
LEVEL lv,
SubStr(sys_connect_by_path(ename,',')||',',
InStr(sys_connect_by_path(ename,',')||',',',',1,Decode(LEVEL,1,2,level)-1)+1,
InStr(sys_connect_by_path(ename,',')||',',',',1,level)-InStr(sys_connect_by_path(ename,',')||',',',',1,Decode(LEVEL,1,2,level)-1)-1) mgr_ename
FROM emp
START WITH mgr IS NULL
CONNECT BY PRIOR empno = mgr


위와 같이 풀어봤습니다 ㅎㅎ

by 손님 [2010.02.10 11:59:17]
똑같이 정렬해서 나오는게 힘드네요 휴

WITH emp AS
(
SELECT 7369 empno, 'SMITH' ename, 7902 mgr FROM dual
UNION ALL SELECT 7499, 'ALLEN' , 7698 FROM dual
UNION ALL SELECT 7521, 'WARD' , 7698 FROM dual
UNION ALL SELECT 7566, 'JONES' , 7839 FROM dual
UNION ALL SELECT 7654, 'MARTIN', 7698 FROM dual
UNION ALL SELECT 7698, 'BLAKE' , 7839 FROM dual
UNION ALL SELECT 7782, 'CLARK' , 7839 FROM dual
UNION ALL SELECT 7788, 'SCOTT' , 7566 FROM dual
UNION ALL SELECT 7839, 'KING' , NULL FROM dual
UNION ALL SELECT 7844, 'TURNER', 7698 FROM dual
UNION ALL SELECT 7876, 'ADAMS' , 7788 FROM dual
UNION ALL SELECT 7900, 'JAMES' , 7698 FROM dual
UNION ALL SELECT 7902, 'FORD' , 7566 FROM dual
UNION ALL SELECT 7934, 'MILLER', 7782 FROM dual
)
SELECT EMP1.EMPNO,
REPLACE(LPAD(' ', (LEVEL-1)) || EMP1.ENAME, ' ', '-') ENAME,
LEVEL,
(SELECT EMP2.ENAME
FROM EMP EMP2
WHERE EMP1.MGR = EMP2.EMPNO(+) )
FROM EMP EMP1
START WITH EMP1.MGR IS NULL
CONNECT BY EMP1.MGR = PRIOR EMP1.EMPNO;

by 마농 [2010.02.10 13:30:09]
스칼라 서브쿼리나 Sys_connect_by_path를 Substr하여 잘 풀어 주셨네요.
하지만 정답은 "헉!"소리 날 정도로 상당히 간단 명료합니다.
계층쿼리만으로 풀리는 문제입니다. 잘 생각해 보세요.

by 쏘쿨 [2010.02.10 15:27:00]
prior ename 사용에 관련된 문제군요.

by Ejql [2010.02.10 15:34:39]
진짜 헉이네요.
혹시나. 컬럼옆에 prior를 붙여볼까(ㅡㅡ;) 해서 해봤더니. 먼가요 이런게 있었나요?
ㅎㄷㄷㄷ

SELECT empno, lpad(ename,length(ename)+level -1,'-'), mgr, level LV,prior ename
FROM emp a
start with empno = 7839
connect by prior empno = mgr;

by 마농 [2010.02.10 16:05:04]
그런게 있었지요. 계층쿼리를 하는 순간 이미 사용하고 계셨구요.
connect by 구문에서 잘 사용하고 있던 구문입니다.
select절에서 사용하실 생각을 못했던 것 뿐이죠.

by jms [2010.05.20 13:34:27]
감사합니다. 관계형데이터베이스 기본 다지기에 좋은 예문이군요
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입