[ Oracle - wm_concat ]

 


1.  
Oracle 에는 비공개된 숨겨진 functions  parameter 다수 존재합니다.

     그 중에서 최근에 알게  것이 "wmsys.wm_concat"라는 함수로 굉장히 강력합니다.

     기능적으로 보면 집약하는 함수라고   있으며, 정규화된 table 비정규화해서 출력하는

     경우에 딱맞습니다. Oracle11g manual에는 기재되어 있지 않기 때문에

     undocumented function(support대상외)이라는 것을 알고 사용하기를 바랍니다.

 

2.  이제 어떤 기능이 되는지 살펴보겠습니다. 우선 다음과 같은 간단한 table 만들어 보겠습니다.

name

description

userid

 

point

취득한 point

getdate

point취득일

 

3.  point 발생할 때마다 table new record 등록이 되므로 userid별로 복수의 records

  존재하게 됩니다. 이렇게 정규화된 table에서 비정규화된 형태(userid별로 point취득일과

  취득한 point 다음의 결과와 같이  행에 표시) 출력하고자 하는 경우에

    wm_concat 사용할  있습니다.

SQL> create table points (userid varchar2(20), point number(10), getdate date);

SQL> insert into points values ('hurjin',100,to_date('2009/04/19','yyyy/mm/dd'));

SQL> insert into points values ('hurjin',50,to_date('2009/05/20','yyyy/mm/dd'));

SQL> insert into points values ('hurjin',300,to_date('2009/05/10','yyyy/mm/dd'));

SQL> insert into points values ('myoyoung',1100,to_date('2009/03/29','yyyy/mm/dd'));

SQL> insert into points values ('myoyoung',40,to_date('2009/04/19','yyyy/mm/dd'));

SQL> insert into points values ('myoyoung',150,to_date('2009/05/01','yyyy/mm/dd'));

SQL> select userid, wmsys.wm_concat(point || '(' || getdate || ')') point_info

   2    from points group by userid order by userid;

userid

point_info

hurjin

100(2009-04-19),300(2009-05-10),50(2009-05-20)

myoyoung

1100(2009-03-29),40(2009-04-19),150(2009-05-01)

 

 

4.  보통 위와 같은 결과를 얻기 위해서는 application쪽에서 coding 하는 경우가 많습니다만,

     wm_concat 사용함으로서  번의 SQL 수행을 통해 결과를 얻을  있습니다.

 

5.   wmsys Workspace Manager metadata 저장하기 위한 schema인데,

     wm_concat함수의 source 암호화되어 있는 관계로  수는 없어서 어떤 식으로 처리를 하는지

      수는 없습니다. 하지만 실행속도는 native function 비슷한 정도로,

     대량의 data test 경우에도 처리속도가 훌륭하더군요.

     아래에서는  하나의 예입니다.

SQL> create table idtable (id number, val varchar2(20));

SQL> insert into idtable (id, val) values (10, 'abc');

SQL> insert into idtable (id, val) values (10, 'abc');

SQL> insert into idtable (id, val) values (10, 'def');

SQL> insert into idtable (id, val) values (10, 'def');

SQL> insert into idtable (id, val) values (20, 'ghi');

SQL> insert into idtable (id, val) values (20, 'jkl');

SQL> insert into idtable (id, val) values (20, 'mno');

SQL> insert into idtable (id, val) values (20, 'mno');

SQL> commit;

SQL> column enames format a50;

 

SQL> select id, wmsys.wm_concat(val) as enames from idtable group by id;

id

val

10

abc,abc,def,def

20

ghi,jkl,mno,mno

 

SQL> select id, wmsys.wm_concat(distinct val) as enames

    2   from idtable group by id order by id;

id

val

10

abc,def

20

ghi,jkl,mno

 

SQL> select id, val, wmsys.wm_concat(val) over(partition by id) as enames

    2   from idtable order by id;

id

val

enames

10

abc

abc,abc,def,def

10

abc

abc,abc,def,def

10

def

abc,abc,def,def

10

def

abc,abc,def,def

20

ghi

ghi,jkl,mno,mno

20

jkl

ghi,jkl,mno,mno

20

mno

ghi,jkl,mno,mno

20

mno

ghi,jkl,mno,mno

 

SQL> select id, val, wmsys.wm_concat(val) over(order by id, val) as enames

2   from idtable order by id;

id

val

enames

10

abc

abc,abc

10

abc

abc,abc

10

def

abc,abc,def,def

10

def

abc,abc,def,def

20

ghi

abc,abc,def,def,ghi

20

jkl

abc,abc,def,def,ghi,jkl

20

mno

abc,abc,def,def,ghi,jkl,mno

20

mno

abc,abc,def,def,ghi,jkl,mno

 

 

6.  database를 DBCA를 이용하지 않고 수동으로 생성하여 "wmsys" schema가 존재하지 않는 경우,

     "$ORACLE_HOME/rdbms/admin/owminst.plb"를 실행하여 생성할 수 있습니다.

'(DB) Oracle > SQL.통계-Connect by' 카테고리의 다른 글

Oracle - connect_by_isleaf  (0) 2017.01.21
Oracle - Connect_By  (0) 2017.01.21
Posted by 농부지기
,

[ Oracle - 레코드를 하나의 컬럼으로 결합 ]

 

 


 


WITH t(type, name, code) AS
(
              
SELECT '과일', '사과', '0' FROM dual
    
UNION ALL SELECT '과일', '레몬', '1' FROM dual
    
UNION ALL SELECT '과일', '포도', '2' FROM dual
    
UNION ALL SELECT '과일', '참외', '3' FROM dual
    
UNION ALL SELECT '채소', '오이', '0' FROM dual
    
UNION ALL SELECT '채소', '당근', '1' FROM dual
    
UNION ALL SELECT '채소', '호박', '2' FROM dual
)
SELECT type
     , 
SUBSTR(XMLAgg(XMLElement(x, ',', name) ORDER BY code).Extract('//text()'), 2) name_9i
     , 
wm_concat(name) name_10g
     , 
ListAgg(name, ',') WITHIN GROUP(ORDER BY code) name_11g
  
FROM t
 
GROUP BY type
 
ORDER BY type ;

 

Posted by 농부지기
,

[ Oracle - connect_by_isleaf  ]

 


 

 
정렬 을 위한 것 에서 사용 될때 마지막 레벨 에 해당 되는 녀석들 만 
조회 값이 '1' 로 조회할수 있게 하는 기능 이다. 
예를 들어 보자 
 
1
    2 -- leaf 에 해당되는 녀석
    3 -- leaf 에 해당되는 녀석
4
   5
       6 -- leaf 에 해당되는 녀석
       7 -- leaf 에 해당되는 녀석
8
   9
       10 -- leaf 에 해당되는 녀석

이런식으로 레벨 별로 디비에 저장 되어 있다고 하자 .
2,3,6,7,10 은 leaf 에 해당된다. 이녀석들은 조회시 
connect_by_isleaf 를 사용 해서 '1' 로 조회할수 있다. 그리고 leaf 가 아닌 녀석들은 '0' 으로 조회된다.
그럼 쿼리 를 만들어 보자 

select NUMBER
      ,CONNECT_BY_ISLEAF AS LEAF
 from NUMBER_ALL
 start with HI_NUMBER is null
 connect by prior NUMBER = HI_NUMBER

그럼 결과는 
NUMBER LEAF
1   0
2   1
3   1
4   0
5   0
6   1
7   1
8   0
9    0
10   1 

이런식으로 connect_by_isleaf 를 사용 하면 레벨 에 상관없이 마지막 하위 레벨의 number 들만 따로 조회 할수 있다. 

 

'(DB) Oracle > SQL.통계-Connect by' 카테고리의 다른 글

Oracle - wm_concat  (0) 2017.01.21
Oracle - Connect_By  (0) 2017.01.21
Posted by 농부지기
,