복붙노트

[SQL] 오라클에서 여러 행에서 CONCATENATE 열 값에 SQL 쿼리

SQL

오라클에서 여러 행에서 CONCATENATE 열 값에 SQL 쿼리

그것으로부터 CONCATENATE 열 값에 SQL을 구성 가능한 것 여러 행?

다음은 예입니다 :

표 A

PID
A
B
C

표 B

PID   SEQ    Desc

A     1      Have
A     2      a nice
A     3      day.
B     1      Nice Work.
C     1      Yes
C     2      we can 
C     3      do 
C     4      this work!

는 SQL의 출력해야한다 -

PID   Desc
A     Have a nice day.
B     Nice Work.
C     Yes we can do this work!

그래서 기본적 내고 테이블의 내림차순 열은 표 B의 SEQ 값의 연결은 무엇입니까?

는 SQL에 어떤 도움?

해결법

  1. ==============================

    1.문자열 집계 기술에 대한 오라클의 설명서를 참조하십시오 - 당신은 버전에 따라 몇 가지 방법이 있습니다. 아주 일반적인 하나는 사용 LISTAGG이다 :

    문자열 집계 기술에 대한 오라클의 설명서를 참조하십시오 - 당신은 버전에 따라 몇 가지 방법이 있습니다. 아주 일반적인 하나는 사용 LISTAGG이다 :

    SELECT pid, LISTAGG(Desc, ' ') WITHIN GROUP (ORDER BY seq) AS description
    FROM B GROUP BY pid;
    

    그런 다음 원하는 PID를 골라에 조인.

    참고 : 박스 아웃, LISTAGG는 VARCHAR2 열이 제대로 작동합니다.

  2. ==============================

    2.11.2 이전 버전에서 작동하는 XMLAGG 기능도있다. WM_CONCAT 오라클에 의해 문서화되지 않은 및 지원되지 않는이기 때문에, 생산 시스템에서 사용하지 않도록 권장합니다.

    11.2 이전 버전에서 작동하는 XMLAGG 기능도있다. WM_CONCAT 오라클에 의해 문서화되지 않은 및 지원되지 않는이기 때문에, 생산 시스템에서 사용하지 않도록 권장합니다.

    XMLAGG 사용하면 다음을 수행 할 수 있습니다 :

    SELECT XMLAGG(XMLELEMENT(E,ename||',')).EXTRACT('//text()') "Result" 
    FROM employee_names
    

    이것이 않는 것은

  3. ==============================

    3.SQL 모델 절 :

    SQL 모델 절 :

    SQL> select pid
      2       , ltrim(sentence) sentence
      3    from ( select pid
      4                , seq
      5                , sentence
      6             from b
      7            model
      8                  partition by (pid)
      9                  dimension by (seq)
     10                  measures (descr,cast(null as varchar2(100)) as sentence)
     11                  ( sentence[any] order by seq desc
     12                    = descr[cv()] || ' ' || sentence[cv()+1]
     13                  )
     14         )
     15   where seq = 1
     16  /
    
    P SENTENCE
    - ---------------------------------------------------------------------------
    A Have a nice day
    B Nice Work.
    C Yes we can do this work!
    
    3 rows selected.
    

    나는 여기에 대해 썼다. 당신이 링크 따르는 경우에 그리고 당신은 성능 비교를 포함하여, 좀 더 찾을 수 OTN을 스레드.

  4. ==============================

    4.LISTAGG 분석 함수는 집계 문자열을 매우 쉽게 그것을 만드는 오라클 11g 릴리스 2 년에 도입되었다. 당신이 릴리스 2를 11g 사용하는 경우 문자열의 집합에 대해이 기능을 사용합니다. 문자열 연결에 대한 자세한 내용은 URL을 아래를 참조하십시오.

    LISTAGG 분석 함수는 집계 문자열을 매우 쉽게 그것을 만드는 오라클 11g 릴리스 2 년에 도입되었다. 당신이 릴리스 2를 11g 사용하는 경우 문자열의 집합에 대해이 기능을 사용합니다. 문자열 연결에 대한 자세한 내용은 URL을 아래를 참조하십시오.

    http://www.oracle-base.com/articles/misc/StringAggregationTechniques.php

    문자열 병합

  5. ==============================

    5.답변 대부분의 제안으로, LISTAGG는 명백한 옵션입니다. 그러나 LISTAGG 하나 개의 성가신 측면은 연결된 문자열의 총 길이는 4000 자 (SQL에서 VARCHAR2에 대한 제한)를 초과하는 경우, 오류가 아래가 12.1 개까지 오라클 버전에서 관리하기가 어렵있는 슬로우됩니다 있다는 것입니다

    답변 대부분의 제안으로, LISTAGG는 명백한 옵션입니다. 그러나 LISTAGG 하나 개의 성가신 측면은 연결된 문자열의 총 길이는 4000 자 (SQL에서 VARCHAR2에 대한 제한)를 초과하는 경우, 오류가 아래가 12.1 개까지 오라클 버전에서 관리하기가 어렵있는 슬로우됩니다 있다는 것입니다

    12cR2에 추가 된 새로운 기능은 LISTAGG의 ON OVERFLOW 절입니다. 같을 것이다이 절을 포함한 쿼리 :

    SELECT pid, LISTAGG(Desc, ' ' on overflow truncate) WITHIN GROUP (ORDER BY seq) AS desc
    FROM B GROUP BY pid;
    

    위는 4000 개 문자로 출력이 제한됩니다하지만 ORA-01489 오류가 발생하지 않습니다.

    이들은 ON 용량 초과 조항의 추가 옵션 중 일부입니다 :

  6. ==============================

    6.LISTAGG를 사용할 수없는 때문에 오라클 9i의 (또는 이전 버전)를 사용하여이 문제를 해결해야하는 사람들을 위해, 당신은 아마, 사용 SYS_CONNECT_BY_PATH해야합니다.

    LISTAGG를 사용할 수없는 때문에 오라클 9i의 (또는 이전 버전)를 사용하여이 문제를 해결해야하는 사람들을 위해, 당신은 아마, 사용 SYS_CONNECT_BY_PATH해야합니다.

    영업 대답하기 위해, 다음 쿼리는 표 A에서 PID를 표시하고 표 B의 모든 DESC 열을 연결합니다 :

    SELECT pid, SUBSTR (MAX (SYS_CONNECT_BY_PATH (description, ', ')), 3) all_descriptions
    FROM (
           SELECT ROW_NUMBER () OVER (PARTITION BY pid ORDER BY pid, seq) rnum, pid, description
           FROM (
                  SELECT a.pid, seq, description
                  FROM table_a a, table_b b
                  WHERE a.pid = b.pid(+)
                 )
          )
    START WITH rnum = 1
    CONNECT BY PRIOR rnum = rnum - 1 AND PRIOR pid = pid
    GROUP BY pid
    ORDER BY pid;
    

    또한 키와 값이 모두 하나 개의 테이블에 포함되는 경우가있을 수 있습니다. 거기에는 표 A 없으며, 단지 표 B가 존재하는 다음 쿼리를 사용할 수 있습니다 :

    SELECT pid, SUBSTR (MAX (SYS_CONNECT_BY_PATH (description, ', ')), 3) all_descriptions
    FROM (
           SELECT ROW_NUMBER () OVER (PARTITION BY pid ORDER BY pid, seq) rnum, pid, description
           FROM (
                  SELECT pid, seq, description
                  FROM table_b
                 )
          )
    START WITH rnum = 1
    CONNECT BY PRIOR rnum = rnum - 1 AND PRIOR pid = pid
    GROUP BY pid
    ORDER BY pid;
    

    원하는 모든 값을 재 배열 할 수있다. 개인 연결된 설명은 PARTITION BY 절에서 다시 정렬 할 수 있으며, PID를 목록이 마지막 ORDER BY 절에서 다시 정렬 할 수 있습니다.

    다른 방법 : 한 행에 전체 테이블의 모든 값을 연결하려는 경우도있을 수 있습니다.

    여기에 설명의 그룹에 대한 인공 값을 사용하고 핵심 아이디어는 연결될 수있다.

    다음 쿼리에서 문자열 상수 '1'사용되지만, 값은 작동합니다 :

    SELECT SUBSTR (MAX (SYS_CONNECT_BY_PATH (description, ', ')), 3) all_descriptions
    FROM (
           SELECT ROW_NUMBER () OVER (PARTITION BY unique_id ORDER BY pid, seq) rnum, description
           FROM (
                  SELECT '1' unique_id, b.pid, b.seq, b.description
                  FROM table_b b
                 )
          )
    START WITH rnum = 1
    CONNECT BY PRIOR rnum = rnum - 1;
    

    개별 연결된 설명은 PARTITION BY 절에서 다시 정렬 할 수 있습니다.

    이 큰 도움이 참조를 언급 한 페이지에 여러 다른 답변 : https://oracle-base.com/articles/misc/string-aggregation-techniques

  7. ==============================

    7.다른 모든 기술은 속도가 느린했다.

    다른 모든 기술은 속도가 느린했다.

  8. ==============================

    8.당신이 선택 쿼리를 실행하기 전에이 작업을 실행 :

    당신이 선택 쿼리를 실행하기 전에이 작업을 실행 :

    SET SERVEROUT ON 크기 6000

    SELECT XMLAGG(XMLELEMENT(E,SUPLR_SUPLR_ID||',')).EXTRACT('//text()') "SUPPLIER" 
    FROM SUPPLIERS;
    
  9. ==============================

    9.이 코드를보십시오 :

    이 코드를보십시오 :

     SELECT XMLAGG(XMLELEMENT(E,fieldname||',')).EXTRACT('//text()') "FieldNames"
        FROM FIELD_MASTER
        WHERE FIELD_ID > 10 AND FIELD_AREA != 'NEBRASKA';
    
  10. ==============================

    10.당신이 당신의 연결을 원하는 위치 선택에서, SQL 함수를 호출합니다.

    당신이 당신의 연결을 원하는 위치 선택에서, SQL 함수를 호출합니다.

    예를 들면 :

    select PID, dbo.MyConcat(PID)
       from TableA;
    

    그런 다음 SQL 함수 :

    Function MyConcat(@PID varchar(10))
    returns varchar(1000)
    as
    begin
    
    declare @x varchar(1000);
    
    select @x = isnull(@x +',', @x, @x +',') + Desc
      from TableB
        where PID = @PID;
    
    return @x;
    
    end
    

    함수 헤더 구문이 잘못 될 수도 있지만 원칙은 작업을 수행합니다.

  11. from https://stackoverflow.com/questions/4686543/sql-query-to-concatenate-column-values-from-multiple-rows-in-oracle by cc-by-sa and MIT license