2009-11-18 6 views
2

몇 가지 집계 함수와 몇 개의 그룹화 된 열이있는 쿼리가 있습니다. 그룹화 된 열 중 하나를 그룹 밖으로 가져 와서 그것이 가지고있는 모든 VARCHAR 값의 일종의 집계 "연결"을 수행하려고합니다. (이상적으로는 새 캐리지 분리 목록에 있음). 여기 오라클 : 그룹화 된 결과에서 그룹화되지 않은 열을 연결하는 방법

내 쿼리 내가이해야 할 위치 나는주의 : Merchant1
: 그래서 본질적으로

SELECT rownum, F.* 
FROM (SELECT 
    c.logical_type "MerchantType", 
    c.merchant_id "MerchantID", 
    c.m_name "MerchantName", 
    m.m_name "TransferredBy", /* <----- Make this aggregate */ 
    SUM(DECODE(b.ba_price,null,0,DECODE(b.BILL_SRVC_ID,'CREDITCHANGE',0,b.ba_price))) "TotalValue", 
    sum(DECODE(b.ba_price,null,0,DECODE(b.BILL_SRVC_ID,'CREDITCHANGE',b.ba_price,0))) "LimitChange", 
    SUM(DECODE(b.ba_status,'bdone',1,0)) "TxnCount", 
    sum(to_number(decode(substr(b.ba_merchant_freetext,1,10),'Commission',substr(b.ba_merchant_freetext, 12,(instr(b.ba_merchant_freetext,';',1,1)-12))))) "Commission" 
FROM bill_auth0 b, 
    merchant0 m, 
    merchant0 c 
WHERE 
    b.srvc_prod_id = 'TRANSFER' 
    AND b.ba_channel = 'WPSS' 
    AND b.ba_status  IN ('bdone') 
    AND b.merchant_id = m.merchant_id 
    AND b.customer_id = c.merchant_id 
    AND b.ba_timestamp BETWEEN to_date('11/01/2009', 'MM/DD/YYYY') 
     AND to_date('11/17/2009', 'MM/DD/YYYY')+1 
GROUP BY 
    c.logical_type, 
    c.merchant_id, 
    c.m_name, 
    m.m_name /* <-- Remove from Grouped By */ 
ORDER BY c.logical_type, c.merchant_id, m.m_name) F; 

을 나는 "TransferredBy는"같이 보일 것입니다 결과를 가질 수 있도록하려면 판매자 2
판매자 3

이 그룹 행에 3 개의 별도의 m.m_name이 있으면 일치합니다.

+0

어떤 오라클 버전입니까? –

답변

0

답장을 무시하십시오. 주석에 대한 응답입니다. (stackoverflow는 어떤 이유로 든 코멘트를 게시 할 수 없습니다. 기존 계정이 기억되기 전에 질문을 올렸습니다.)

나는 버전이 10g라고 생각한다.

+0

@ 리치 : 질문을 편집하려면 링크 (http://stackoverflow.com/posts/1757394/edit)가 있어야합니다. 당신은 질문에이 정보를 추가 할 수 있습니다, 그것은 독자들에게 더 분명해질 것입니다. –

+0

그게 문제입니다. 내가 질문을 올렸을 때 임시 미등록 사용자로 인증 받았고, 잠시 동안 여기에 없었으며 심지어 댓글 게시를위한 50 평판 임계 값이나 실제로 내 로그인에 대해 인식하지 못했습니다. 계정이 FUBAR 일 것입니다. 얼마나 지저분한 지 유감스럽게 생각합니다.하지만 지금 할 수있는 최선의 방법은이 의견 체인을 실행하는 것입니다. – Rich

3

문제를 해결할 수있는 기본 제공 기능을 알 수는 없지만 그럴 수있는 것은 you can write your own aggregate function입니다.

유형 사양 :

CREATE OR REPLACE TYPE TextConcatenation AS OBJECT 
(

    text VARCHAR2(10000), 
    delimiter VARCHAR2(10), 
    concatenation_count NUMBER, 

    STATIC FUNCTION ODCIAggregateInitialize(actx IN OUT TextConcatenation) RETURN NUMBER, 

    MEMBER FUNCTION ODCIAggregateIterate(self IN OUT TextConcatenation, val IN VARCHAR2) RETURN NUMBER, 

    MEMBER FUNCTION ODCIAggregateTerminate(self IN TextConcatenation, returnValue OUT VARCHAR2, flags IN NUMBER) RETURN NUMBER, 

    MEMBER FUNCTION ODCIAggregateMerge(self IN OUT TextConcatenation, ctx2 IN TextConcatenation) RETURN NUMBER 

) 

유형 본체 :

CREATE OR REPLACE TYPE BODY TextConcatenation AS 

    STATIC FUNCTION ODCIAggregateInitialize(actx IN OUT TextConcatenation) RETURN NUMBER IS 
    BEGIN 
    IF actx IS NULL THEN 
     actx := TextConcatenation('', ', ', 0); #substitute your own delimiter here in the second argument 
    ELSE 
     actx.text := ''; 
     actx.delimiter := ', '; # substitute your own delimiter here 
     actx.concatenation_count := 0; 
    END IF; 
    RETURN ODCIConst.Success; 
    END; 

    MEMBER FUNCTION ODCIAggregateIterate(self IN OUT TextConcatenation, val IN VARCHAR2) RETURN NUMBER IS 
    BEGIN 
    IF self.concatenation_count > 0 THEN 
     self.text := self.text || delimiter; 
    END IF; 

    self.text := self.text || val; 

    self.concatenation_count := self.concatenation_count + 1; 

    RETURN ODCIConst.Success; 
    END; 

    MEMBER FUNCTION ODCIAggregateTerminate(self IN TextConcatenation, returnValue OUT VARCHAR2, flags IN NUMBER) RETURN NUMBER IS 
    BEGIN 
    returnValue := text; 
    RETURN ODCIConst.Success; 
    END; 

    MEMBER FUNCTION ODCIAggregateMerge(self IN OUT TextConcatenation, ctx2 IN TextConcatenation) RETURN NUMBER IS 
    BEGIN 
    IF ctx2.concatenation_count > 0 THEN 
     IF self.concatenation_count > 0 THEN 
     self.text := self.text || delimiter || ctx2.text; 
     ELSE 
     self.text := ctx2.text; 
     END IF; 
     self.concatenation_count := self.concatenation_count + ctx2.concatenation_count; 
    END IF; 

    RETURN ODCIConst.Success; 
    END; 

END; 

의 I는 호기심 때문에, 나는 구분자로 텍스트를 연결합니다 사용자 정의를 구현, 집계 함수에서 내 손을 시도 집계 함수 :

CREATE OR REPLACE FUNCTION text_concatenate(text VARCHAR2) RETURN VARCHAR2 AGGREGATE USING TextConcatenation; 

이 모든 후, 나는 다음 쿼리를 실행할 수 있었다. : 여기

Paynter, Adam 
5

다른 string aggregation techniques에 대한 좋은 기사입니다 :

SELECT text_concatenate(name) FROM 
(
    SELECT 'Paynter' name FROM DUAL 
    UNION ALL 
    SELECT 'Adam' name FROM DUAL 
) 

결과는 단일 행이었다.

나는 아직 다른 방법 (XML 기반)를 추가 할 수 있습니다

select rtrim(
     extract(
      sys_xmlagg(
      xmlelement("X",ename||', ') 
      ), 
      '/ROWSET/X/text()' 
     ).getstringval(), 
     ', ' 
     ) 
    from emp; 

그리고 11g 릴리스 2

우리는 마침내 내장되어 LISTAGG 기능.

0

시험해보기 wm_concat(yourColumn) ... db 버전에 따라 사용할 수 있습니다. 공식적으로 문서화 된 함수는 아니지만 위에 나열된 다른 많은 함수와 동일한 기능을 수행합니다.

이것은 쉼표로 구분 된 목록을 만듭니다. 또 다른 팁이 wm_concat 내에서 서로 다른 사용하는 것입니다

) (당신이 그것을 둘러싸고있는 새 라인 문자가 대체 얻으려면()와 같은wm_concat (별개의 yourColumn)와 같은 그래서 당신은 중복을하지 않는 것이.

관련 문제