sourcetip

Oracle의 여러 행에서 열 값을 연결하기 위한 SQL 쿼리

fileupload 2023. 3. 19. 18:26
반응형

Oracle의 여러 행에서 열 값을 연결하기 위한 SQL 쿼리

여러 행에서 열 값을 연결하기 위해 SQL을 구성할 수 있습니까?

다음은 예를 제시하겠습니다.

표 A

PIDabc

표 B

PID SEQ 설명
A 1 HaveA 2 a nice3일.
B 1 수고하셨습니다.
C 1 있음C 2 할 수 있다C 3 doC 4 이 일!

SQL 출력은 다음과 같습니다.

PID 설명A 좋은 하루 되세요.
B 수고하셨습니다.
C 네, 우리는 이 일을 할 수 있어요!

즉 기본적으로 출력 테이블의 Desc 열은 표 B의 SEQ 값을 연결한 것입니까?

SQL에 대해 도움이 필요하십니까?

사용하고 있는 버전에 따라 몇 가지 방법이 있습니다.문자열 집약 기술에 관한 Oracle 문서를 참조해 주십시오.매우 일반적인 방법은 다음과 같습니다.

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

후, 「」에 참가합니다.Apids는는원원원원원

주의: 개봉 후LISTAGG와만 올바르게 동작합니다.VARCHAR2컬럼을 클릭합니다.

'아주머니'라는 것도 있어요.XMLAGG11.2로 하다 ★★★★★★★★★★★★★★★★★★WM_CONCAT는 Oracle에서 문서화되어 지원되지 않으므로 운영 시스템에서는 사용하지 않는 것이 좋습니다.

★★★★★★★★★★★★★★★★ XMLAGG을 사용하다

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

이게 하는 일은

  • ename을로 표시합니다).employee_names요소 포함)xml " " ( "E " )
  • 이 글을 발췌하다
  • xml을 집약(연결)
  • 결과 열을 "Result"라고 부릅니다.

SQL model 절의 경우:

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 스레드 링크를 클릭하면 성능 비교 등 더 많은 정보가 표시됩니다.

LISTAGG 분석 기능은 Oracle 11g Release 2에서 도입되어 문자열을 매우 쉽게 집약할 수 있습니다.11g Release 2 를 사용하고 있는 경우는, 문자열 집약에 이 기능을 사용할 필요가 있습니다.문자열 연결에 대한 자세한 내용은 아래 URL을 참조하십시오.

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

문자열 연결

의 알 수 , ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」LISTAGG확실한 선택입니다.,, 한, 한, 한, aspect, aspect, aspect, aspect, aspect, aspect, aspect, aspect, aspect, aspect, aspect, aspect, aspect, LISTAGG의 총 ('4000'의 :VARCHAR2이 에러는 버전에서는 하기 어렵습니다.

ORA-01489: 문자열 연결 결과가 너무 깁니다.

은 12cR2 입니다.ON OVERFLOW의 절LISTAGG과 같습니다

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

되지만 4000자, 4000자, 4000자, 4000자 등은 슬로우 .ORA-01489

입니다.ON OVERFLOW§:

  • ON OVERFLOW TRUNCATE 'Contd..' 라고 표시됩니다.'Contd..'은 " " " " 입니다....)
  • ON OVERFLOW TRUNCATE '': 4000달러
  • ON OVERFLOW TRUNCATE WITH COUNT: 에 총 종료문자뒤에끝에총문자수가표시됩니다.- ' - '...(5512)
  • ON OVERFLOW ERROR: 이 the the 가 예상되는 LISTAGGORA-01489입니다).error( 「 「 」 「 。

Oracle 9i 이전 버전을 사용하여 이 문제를 해결해야 하는 경우 SYS_CONNECT_를 사용해야 합니다.BY_PATH, LISTAGG를 사용할 수 없기 때문에

OP에 응답하기 위해 다음 쿼리는 표 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;

키와 값이 모두 1개의 테이블에 포함되는 경우도 있습니다.다음 쿼리는 테이블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;

연결된 개별 설명은 파티션 기준 절에서 순서를 변경할 수 있습니다.

이 페이지의 다른 몇 가지 답변에서도 이 매우 도움이 되는 레퍼런스에 대해 언급하고 있습니다.

  1. LISTAGG는 정렬이 필수인 경우 최고의 성능을 발휘합니다(00:00:05.85).

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

  2. COLLECT는 정렬이 필요하지 않은 경우 최고의 성능을 제공합니다(00:00:02.90).

    SELECT pid, TO_STRING(CAST(COLLECT(Desc) AS varchar2_ntt)) AS Vals FROM B GROUP BY pid;

  3. 주문 시 Collect가 조금 느립니다(00:00:07.08).

    SELECT pid, TO_STRING(CAST(COLLECT(Desc ORDER BY Desc) AS varchar2_ntt)) AS Vals FROM B GROUP BY pid;

다른 모든 기술들은 더 느렸다.

선택 쿼리를 실행하기 전에 다음 작업을 수행합니다.

SET SERVEROUT ON SIZE 6000

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

다음 코드를 사용해 보십시오.

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

연결할 위치에서 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

Function Header 구문이 잘못될 수 있지만 이 원칙은 작동합니다.

언급URL : https://stackoverflow.com/questions/4686543/sql-query-to-concatenate-column-values-from-multiple-rows-in-oracle

반응형