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.