0

나는 같이 GROUP_CONCAT 문 내 기존 데이터베이스에 대한 SQL 코드의 여러 라인을 가지고 :PostgreSQL에서 GROUP_CONCAT 함수를 정의 할 수 있습니까?

SELECT SUM(age), GROUP_CONCAT(sal) FROM Users; 

PostgreSQL을, 난과 같은 작업을 수행 할 수 있습니다

SELECT SUM(age), string_agg(sal, ', ') FROM Users; 

나는를 재사용하고 싶습니다 오래된 SQL을 최대한 많이 사용합니다. 그래서 내부적으로 string_agg을 호출하는 GROUP_CONCAT 함수를 정의해야합니다. 이것이 가능한가?

편집 : 연결된 질문과 관련이 없습니다!

내 질문에 "group_concat이라는 함수를 정의하는 방법"이라고 묻습니다. 링크 된 질문은 "어떻게 우리가 (새로운 함수를 정의하지 않고) 그룹 concat과 동일한 것을 할 수 있는가?"라고 말합니다. 답변도없고, 내가 원하는 것과 일치합니다.

선택한 답변은 다음과 같습니다. 고맙게도 닫히기 전에 대답했습니다.

답변

2

당신이 원하는 것을 이는 string_agg() 내장있다, 그러나 MySQL의 호환성을 위해 이름 GROUP_CONCAT 할 수 있도록 특별히 질문 등은 이미 끝났다 https://github.com/2ndQuadrant/mysqlcompat/blob/master/sql_bits/aggregate.sql 한 번 봐 가지고. 유감스럽게도, string_agg()는 누적에 내부 데이터 형식을 사용합니다 (아마도 각 추가시 전체 버퍼를 복사하지 않기 때문에 소스를 보지 못했을 것입니다). 그리고 SQL aggrerate를 string_agg와 동일하게 선언하는 방법을 찾지 못했습니다.).

group_concat() 함수를 정의하는 것은 작동하지 않습니다. pg는 내부적으로 숨겨진 집계가 아닌 집계임을 인식해야하므로 작동하지 않습니다. 이러한 함수는 한 번에 하나의 행에서 작동합니다. 내부의 집계는 단일 행을 집계하여 변경되지 않은 상태로 반환합니다 ...

따라서이 코드는 요소를 배열에 누적 한 다음 " 구분자와 array_to_string. array_agg() 선언 (모델이되기 전에)을 모델로 사용하고 집계 배열을 텍스트로 변환하는 finalizer 함수를 추가하기 만하면됩니다.

CREATE OR REPLACE FUNCTION _group_concat_finalize(anyarray) 
RETURNS text AS $$ 
    SELECT array_to_string($1,',') 
$$ IMMUTABLE LANGUAGE SQL; 

CREATE AGGREGATE group_concat(anyelement) (
    SFUNC=array_append, 
    STYPE=anyarray, 
    FFUNC=_group_concat_finalize, 
    INITCOND='{}' 
); 

SELECT group_concat(x) FROM foo; 

좋은 것은

는, 번거 로움없이, 모든 유형의 일반 유형 "anyarray"와 "anyelement"덕분에 잘 작동해야한다는 것입니다.

string_agg가 각 추가시 전체 집계 배열을 실제로 복사하지 않으면이 작업은 string_agg()보다 느릴 것이라고 예상합니다. 그러나 각 세트로 그룹화 할 행 수가 많은 경우에만 중요합니다. 내 열이 숫자 형식을 반환로 연결된 코드가 작동하지 않습니다)

http://sqlfiddle.com/#!17/c452d/1

+0

테스트를 거쳐 예상대로 작동합니다! 이 솔루션의 핵심은 모든 유형에서 작동한다는 것입니다. – Jus12

+0

행 수가 100 개 미만입니다. 따라서이 부분은 훌륭하게 보입니다. – Jus12

2

예 가능합니다.

-- GROUP_CONCAT() 
-- Note: only supports the comma separator 
-- Note: For DISTINCT and ORDER BY a subquery is required 
CREATE OR REPLACE FUNCTION _group_concat(text, text) 
RETURNS text AS $$ 
    SELECT CASE 
    WHEN $2 IS NULL THEN $1 
    WHEN $1 IS NULL THEN $2 
    ELSE $1 operator(pg_catalog.||) ',' operator(pg_catalog.||) $2 
    END 
$$ IMMUTABLE LANGUAGE SQL; 

CREATE AGGREGATE group_concat (
    BASETYPE = text, 
    SFUNC = _group_concat, 
    STYPE = text 
); 
+0

이 경우에, 당신은 아마 SQL 쿼리를 편집 분을 보낼 수 있습니다. 'function group_concat (numeric) 함수가 존재하지 않습니다. 힌트 : 지정된 이름 및 인수 유형과 일치하는 함수가 없습니다. 당신은 명시 적 타입 캐스트를 추가해야 할 수도 있습니다 .' – Jus12

+0

그런 다음 실제로 SQL을 변경하거나 SQL 쿼리에서 값을 텍스트로 변환하려는 경우 숫자 값에 대한 group_concat() 집계를 추가하십시오. –

+0

SQL 쿼리는 컴파일 된 코드이므로 변경하는 것은 옵션이 아닙니다. 숫자 형을 시도 할 것입니다. 나는 링크에서 구문을 이해하지 못한다. 거기에 어떤 참조? – Jus12