2012-11-09 3 views
0

SQL에서 XMLAGG를 사용하는 중에 문제가 있습니다.XMLAGG에서 중복 레코드 사용

나는 반복 할 수있는 여러 레코드가있는 테이블이 있습니다. 테이블에는 고객 주소와 고객 이름이 포함됩니다.

Create Table cust_data(
    cust_name varchar2(30), 
    cust_addr_line1 varchar2(300), 
    cust_addr_line2 varchar2(300), 
    cust_addr_line3 varchar2(300), 
    cust_addr_type varchar2(3)); 

표에는 단일 고객 이름 및 다른 주소 유형에 대한 여러 레코드가 포함될 수 있습니다.

또한 단일 고객의 경우 동일한 유형의 주소가 여러 개있을 수 있습니다.

그래서 고객이 내가 쉼표로 구분 된 형식으로 old_addresses 모든 고객의 이름을 꺼내하려는 나는 선택이

cust1 address1 curr_address 
cust1 address2 old_address 
cust1 address3 old_address 
cust1 address4 old_address 
cust2 address5 curr_address 
cust2 address6 old_address 

같은 주소를 가질 수 있습니다.

cust1, cust1, cust1, cust2,

어떻게 출력을 얻는다 :이를 이용한

나는 다음과 같은 SQL 나는 다음과 같은 출력을 얻을

select XMLAGG(XMLELEMENT(E, cust_name || ',')).EXTRACT('//text()') 
from cust_data where cust_addr_type ='old_address'; 

을 사용 예 :

cu st1, cust2

도와주세요.

편집 # 1 :

다른 테이블은 다음과 같이 수행 할 수 있습니다

Create Table cust_info(
    cust_name varchar2(30), 
    Cust_account varchar2(300), 
    cust_amount_paid varchar2(300), 
    cust_amount_pend varchar2(300), 
    cust_payment_type varchar2(300)); 

Create Table payment_master_info(
    pmnt_type varchar2(30), 
    pmnt_desc varchar2(300), 
    pmnt_rate varchar2(300), 
    pmnt_tenure varchar2(300)); 

쿼리는 다음과 같이이다 :

SELECT XMLAGG(XMLELEMENT(E, CUST_NAME || ',')) .EXTRACT('//text()'), 
      CD.CUST_ADDR_LINE1, 
      CD.CUST_ADDR_LINE2, 
      CD.CUST_ADDR_LINE3, 
      CI.CUST_AMOUNT_PAID, 
      CI.CUST_AMOUNT_PEND, 
      CI.CUST_ACCOUNT 
    FROM CUST_INFO CI, PAYMENT_MASTER_INFO PM, CUST_DATA CD 
WHERE CD.CUST_NAME = CI.CUST_NAME 
    AND CI.CUST_PAYMENT_TYPE = PM.PMNT_TYPE 
    AND CUST_ADDR_TYPE = 'old_address'; 

이제 데이터를이 거대한에. pmnt_type의 데이터 범위는 10000-15000 데이터 범위는 이고 다른 테이블의 데이터 범위는 2100000-5000000입니다.

고유 데이터에 대한 내부 쿼리를 적용하면 성능이 기하 급수적으로 떨어집니다.

다른 방법이 있습니까?

편집 # 2 : 또한이 내부 쿼리를 사용하는 동안 실행 중에 ORA-19011 (: 문자 버퍼가 너무 작음) 오류가 발생했습니다. 어떤 이유가있을 수 있습니까?

+0

은'ORA-19011'은 PL/SQL 오류입니다, 당신은 그것의 변수에 대해 너무 큰 값을 넣어하려고하는 것을 의미한다. 아마도 XMLAGG를 VARCHAR2에 넣었을 것입니다 :'extract' 메소드는 VARCHAR2보다 큰 XMLTYPE을 생성합니다. –

+0

그건 그렇고 당신의 질문은 의미가 없습니다. 주소 테이블을 그룹화하는 동안 왜'cust_addr_linei'를 선택하겠습니까? 귀하의 질의는 [컴파일되지 않습니다] (http://www.sqlfiddle.com/#!4/38f34/1).우리는 여전히 많은 정보를 잃어 버렸습니다 : 계획, 인덱스, 카디널리티, 기본 키를 설명하십시오 ... –

+0

먼저 면책 조항을 써야합니다 : 이것은 모범 사례 샘플입니다. 나는 미안하지만 어떤 포럼에서도 정확한 코드를 올릴 수 없다. 나는 그것에 곤경에 빠질 수있다. 주어진 기초 위에 건설하려고 노력하십시오. –

답변

2

당신은 내부 쿼리에서 DISTINCT를 사용할 수 있습니다

SQL> select XMLAGG(XMLELEMENT(E, cust_name || ',')).EXTRACT('//text()') 
    2 from (SELECT distinct cust_name, cust_addr_type FROM cust_data) 
    3 where cust_addr_type ='old_address'; 

XMLAGG(XMLELEMENT 
----------------- 
cust1,cust2, 
+0

사실이 문제가 있습니다. 당신은 테이블에 엄청난 데이터가 포함되어 있고 쿼리가 이것에만 국한되지 않는다는 것을 알 수 있습니다. 다른 테이블에도 여러 개의 조인이 있습니다. 필자는 내부 쿼리를 사용하여 성능을 완전히 잃었습니다. 나는 이미 쿼리에 최적의 조인을 적용하여 시스템이 느려지는 것을 계속합니다. –

+0

더 이상의 정보가 없으면 쿼리 성능을 향상시킬 수 있는지 여부를 알기가 어렵습니다. –

+0

지금 도움주세요, 질문을 편집했습니다. –