database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
PostgreSQL
Firebird
ㆍOracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
Oracle Q&A 40331 게시물 읽기
No. 40331
계층구조 상위 집계 방법에 대하여 문의드립니다.
작성자
김흥수(protokhs)
작성일
2013-12-06 19:02
조회수
7,793

아래와 같은 계층 테이블이 있습니다.

with recur as

(

select 1 id , null amt , null p_id from dual union all

select 2 id , 303 amt , 1 p_id from dual union all

select 3 id , 188 amt , 1 p_id from dual union all

select 4 id , null amt , null p_id from dual union all

select 5 id , null amt , 4 p_id from dual union all

select 6 id , 412 amt , 5 p_id from dual union all

select 7 id , 678 amt , 5 p_id from dual union all

select 8 id , 583 amt , null p_id from dual

 

)

select

a.id

, a.amt

, a.p_id

from recur a

connect by

prior a.id = a.p_id

start with a.p_id is null

order siblings by

a.id

 

==>

ID AMT P_ID

1

2 303 1

3 188 1

4

5 4

6 412 5

7 678 5

8 583

 

 

상위로 집계하여

 

ID AMT P_ID AMTSUM

1 491

2 303 1 303

3 188 1 188

4 1090

5 4 1090

6 412 5 412

7 678 5 678

8 583 583

 

 

이런 결과를 얻고 싶습니다.

 

그런데 문제는 데이타가 엄청 많고(1000만 건 중에서 대략 2~3만 건을 select 하여 집계)

집계할 컬럼이 amt1,amt2,amt3.... 이런 식으로 많습니다.

가장 효과적인 방법이 어떤 것이 있을까요?

이 글에 대한 댓글이 총 6건 있습니다.

 스칼라 서브쿼리에서 건바이건으로 하위 데이터를 집계

ex)

 

with recur as

(

select 1 id , null amt , null p_id from dual union all

select 2 id , 303 amt , 1 p_id from dual union all

select 3 id , 188 amt , 1 p_id from dual union all

select 4 id , null amt , null p_id from dual union all

select 5 id , null amt , 4 p_id from dual union all

select 6 id , 412 amt , 5 p_id from dual union all

select 7 id , 678 amt , 5 p_id from dual union all

select 8 id , 583 amt , null p_id from dual

 

)

select

a.id

, ( SELECT SUM (AMT) FROM RECUR START WITH ...... )

, a.amt

, a.p_id

from recur a

connect by

prior a.id = a.p_id

start with a.p_id is null

order siblings by

하지만 건수가 많아 느린건 문제가 될거같네요.

 

채용근(taiji97)님이 2013-12-06 21:57에 작성한 댓글입니다.

채용근님 관심 감사합니다.

 

말씀하신대로 쿼리를 구성해서 제 로컬 pc에서 수행해 보았습니다.(서버에서는 권한이 없어서리..)

 

테스트해보니

32087 건 / 11908941 건 인 자료에서

그냥 계층 쿼리만 수행하니 3초 정도 걸렸구요

집계 컬럼이 1개 일 때 3.6초

2개 일때 4.2~3초

...

5개일때 6초 전후한 시간이 걸렸습니다.

 

더 좋은 방법은 없을까요?

김흥수(protokhs)님이 2013-12-08 14:19에 작성한 댓글입니다.

Start With 절을 지정하지 않고 계층쿼리를 전개합니다.
그러면 모든 행이 시작점이 되는 거죠.
그후 connect_by_root 를 이용해 group by sum 하시면 됩니다.


SELECT empno
     , SUM(sal)
  FROM (SELECT CONNECT_BY_ROOT(empno) empno
             , sal
          FROM emp
         CONNECT BY PRIOR empno = mgr
        )
 GROUP BY empno
;

마농(manon94)님이 2013-12-09 09:11에 작성한 댓글입니다.

마농님 감사합니다.

그런데 마농님 말씀대로 하면 출력 순서는 어떻게 하지요?

김흥수(protokhs)님이 2013-12-09 10:47에 작성한 댓글입니다.

-- 집계용 쿼리와 본래의 계층 쿼리는 별도로 가야겠지요. --
SELECT a.empno
     , a.mgr
     , a.sal
     , b.sal_1
     , b.sal_2
     , b.sal_3
  FROM emp a
     , (SELECT empno
             , SUM(sal) AS sal_1
             , SUM(sal*0.1) AS sal_2
             , SUM(sal+NVL(comm,0)) AS sal_3
          FROM (SELECT CONNECT_BY_ROOT(empno) empno
                     , sal
                     , comm
                  FROM emp
                 CONNECT BY PRIOR empno = mgr
                )
         GROUP BY empno
        ) b
 WHERE a.empno = b.empno
 START WITH a.mgr IS NULL
 CONNECT BY PRIOR a.empno = a.mgr
 ORDER SIBLINGS BY a.empno
;

마농(manon94)님이 2013-12-09 10:57에 작성한 댓글입니다.

마농님이 제시하신 방법을 사용하여 테스트한 결과

컬럼의 갯수가 늘어도 3.6초 안쪽으로 떨어집니다.

스칼라 서브쿼리는 컬럼 갯수에 영향을 받는데 마농님 방법은 영향을 받지 않네요

 

또 다른 방법은 없을까요?

김흥수(protokhs)님이 2013-12-09 13:17에 작성한 댓글입니다.
[Top]
No.
제목
작성자
작성일
조회
40335시퀀스 권한 문제... [1]
김정훈
2013-12-10
6323
40334알파벳,숫자 조합 순차 채번 문의 [3]
등촌블루스
2013-12-10
8688
40332select 후 insert 질문 드립니다 [5]
진현철
2013-12-09
7007
40331계층구조 상위 집계 방법에 대하여 문의드립니다. [6]
김흥수
2013-12-06
7793
40330outter조인을 할 수 없는 커리문이라서 문의 드립니다. [11]
야간비행
2013-12-06
7841
40329select 할때 order by 질문 드립니다 [7]
진현철
2013-12-06
6862
40328서로 다른 seq를 가진 데이터를 조회하려고 합니다. [5]
초봉이
2013-12-05
5883
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.017초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다