PostgreSQL GROUP_CONCAT에 해당합니까?


248

테이블이 있고 필드 값이 연결된 id 당 하나의 행을 가져오고 싶습니다.

예를 들어 내 테이블에는 다음이 있습니다.

TM67 | 4  | 32556
TM67 | 9  | 98200
TM67 | 72 | 22300
TM99 | 2  | 23009
TM99 | 3  | 11200

그리고 나는 출력하고 싶습니다 :

TM67 | 4,9,72 | 32556,98200,22300
TM99 | 2,3    | 23009,11200

MySQL에서는 집계 함수를 사용할 수 GROUP_CONCAT있었지만 여기서는 작동하지 않는 것 같습니다 ... PostgreSQL과 동등한 기능이 있습니까?


답변은 아니지만 postgresonline.com/journal/index.php?/archives/…를 확인하십시오 .
Kuberchaun



1
가장 좋은 대답은 여전히 ​​다른 질문에 있다고 생각합니다. stackoverflow.com/a/47638417/243233
Jus12

답변:


237

이것은 아마도 좋은 출발점이 될 것입니다 (버전 8.4 이상) :

SELECT id_field, array_agg(value_field1), array_agg(value_field2)
FROM data_table
GROUP BY id_field

array_agg 는 배열을 반환하지만 필요에 따라 텍스트를 작성하고 편집 할 수 있습니다 (아래 설명 참조).

버전 8.4 이전에는 사용하기 전에 직접 정의해야합니다.

CREATE AGGREGATE array_agg (anyelement)
(
    sfunc = array_append,
    stype = anyarray,
    initcond = '{}'
);

(PostgreSQL 문서에서 그린)

설명 :

  • 배열을 텍스트로 캐스트 한 결과는 결과 문자열이 중괄호로 시작하고 끝나는 것입니다. 이러한 괄호는 원하지 않는 경우 일부 방법으로 제거해야합니다.
  • ANYARRAY를 TEXT로 캐스팅하면 포함 된 쉼표가 포함 된 요소가 출력에서 ​​표준 CSV 스타일로 이중 인용되므로 CSV 출력을 가장 잘 시뮬레이션합니다. array_to_string () 또는 string_agg () (9.1에 추가 된 "group_concat"함수)는 쉼표가 포함 된 문자열을 인용하지 않으므로 결과 목록에 요소 수가 잘못됩니다.
  • 새로운 9.1 string_agg () 함수는 먼저 내부 결과를 TEXT로 캐스트하지 않습니다. 따라서 value_field가 정수이면 "string_agg (value_field)"는 오류를 생성합니다. "string_agg (value_field :: text)"가 필요합니다. array_agg () 메서드는 집계 후 값당 캐스트가 아닌 하나의 캐스트 만 필요합니다.

1
그리고 9.0에서 당신은 listagg ()를 가질 것입니다
Scott Bailey

6
CSV를 얻으려면 쿼리는 SELECT id_field, array_to_string (array_agg (value_field1), ','), array_to_string (array_agg (value_field2), ',')이어야합니다. FROM data_table GROUP BY id_field
Nux

2
여기서는 array_to_string을 사용할 수 없습니다. value_field에 쉼표가 포함되어 있으면 결과 CSV가 올바르지 않습니다. array_agg ()를 사용하고 TEXT로 캐스트하면 쉼표가 포함 된 문자열을 올바르게 인용합니다. 유일한주의 사항은 시작 및 끝 중괄호도 포함한다는 것이므로 내 진술은 "필요에 따라 편집하십시오". 그 점을 명확히하기 위해 편집하겠습니다.
Matthew Wood


256

9.0 이후 로 훨씬 더 쉽습니다.

SELECT id, 
       string_agg(some_column, ',')
FROM the_table
GROUP BY id

32
구문을 사용하면 문자열 또는 값을 사용하여 배열의 값 순서를 array_agg예를 들어 string_agg(some_column, ',' ORDER BY some_column)또는 심지어 다음과 같이 지정할 수도 있습니다.string_agg(surname || ', ' || forename, '; ' ORDER BY surname, forename)
IMSoP

8
그것은 그 끝내 distinct하나가 사용할 수 있도록, string_agg와 작품string_agg(distinct some_solumn, ',')
아룬

3
열 값이 TEXT문자열이 아닌 값 (예 :) 인 경우 열 값을 캐스트해야 할 수도 있습니다 uuid. 이것은 다음과 같습니다string_agg(some_column::text, ',')
Kendall

48
SELECT array_to_string(array(SELECT a FROM b),', ');

그렇습니다.


이 주석 에서와 같이 특정 순서로 집계 하는 것이 가능 합니까? 한 열을 기준으로 그룹화하고 다른 열을 기준으로 순서를 어떻게 처리합니까 (예 : 세로 데이터 집합 내에서 변수를 연결)?
Michael A

15

이렇게 해보십시오 :

select field1, array_to_string(array_agg(field2), ',')
from table1
group by field1;

2

배열 유형 에서 작동하는 버전 :

select
  array_to_string(
    array(select distinct unnest(zip_codes) from table),
    ', '
);

@max_spy도 5 년 전에 같은 말을하였습니다.
Emil Vikström

@ EmilVikström : 틀릴 권리가 있지만주의 깊게 읽으십시오. 그것은 다르지만, zip_codes와 같은 배열 유형에서 작동하는 예제를 제공했습니다 character varying(5)[]. 또한, 나는 내 목적을 위해-unnest가 필요하다는 것을 확인했다 ERROR: cannot accumulate arrays of different dimensionality. 그렇지 않으면 당신은 볼 것이다 .
Sławomir Lenart 2013

1

postgresql에서 나의 sugestion

SELECT cpf || ';' || nome || ';' || telefone  
FROM (
      SELECT cpf
            ,nome
            ,STRING_AGG(CONCAT_WS( ';' , DDD_1, TELEFONE_1),';') AS telefone 
      FROM (
            SELECT DISTINCT * 
            FROM temp_bd 
            ORDER BY cpf DESC ) AS y
      GROUP BY 1,2 ) AS x   

1
ORDER BY내부 쿼리에서 왜하고 있습니까? 어쨌든 주문이 손실되지 않습니까?
mypetlion

-1

오라클 쿼리가 작동하기를 바랍니다.

Select First_column,LISTAGG(second_column,',') 
    WITHIN GROUP (ORDER BY second_column) as Sec_column, 
    LISTAGG(third_column,',') 
    WITHIN GROUP (ORDER BY second_column) as thrd_column 
FROM tablename 
GROUP BY first_column

rextester.com/l/postgresql_online_compiler 에서 테스트했지만 작동하지 않았습니다. 42883 : function listagg (text, unknown, text) does not exist
Manuel Romeiro

오라클은 postgres와 다른 구문과 기능을 가지고 있습니다.
Herman J. Radtke III
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.