0

私はのように、GROUP_CONCAT文と私のレガシーデータベースのSQLコードの数行を持っている:私は再利用したいと思いますPostgreSQLでGROUP_CONCAT関数を定義できますか?

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

:PostgreSQLで

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

、私は同じことを行うことができます古いSQLを可能な限り多く使用します。だから私は内部でstring_aggを呼び出すGROUP_CONCAT関数を定義する必要があります。これは可能ですか?

EDIT:リンクされた質問は無関係です!

私の質問は「どのようにgroup_concatという関数を定義するのですか?」と尋ねます。リンクされた質問は、「どのようにして、(新しい関数を定義することなく)連結をグループ化することができますか?答えのどれも、私が望むものと一致しません。

選択した回答が上です!ありがたいことに、それは閉じられる前に答えられました。

答えて

2

あり何をしたいんstring_agg()組み込みはあるが、それはMySQLの互換性のためGROUP_CONCAT名前を付けるために、あなたは、具体的尋ねます。残念ながら、string_agg()は蓄積のために内部データ型を使用しています(おそらく、各追加時にバッファ全体をコピーするのを避けるために、私はソースを見ていません)、SQL集約をstring_aggと同じに宣言する方法)。

group_concat()関数の定義は、pgが集約であることを意識する必要があります。内部で集約を隠している関数では機能しません。そのような関数は、一度に1行で動作します。内部の集合体は単一行を集約してそのまま返します。

したがって、このコードは要素を配列に累積し、配列_to_stringを持つ区切り文字。モデルとしてarray_agg()宣言(組み込みになる前)を使用し、集約配列をテキストに変換するファイナライザ関数を追加するだけです。

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()よりも遅くなると推測します。ただし、これは各セットにグループ化される行の数が多い場合にのみ重要です。この場合、あなたはおそらくSQLクエリを編集分を過ごすことができます;)

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

+0

テスト済みで、期待どおりに動作します!このソリューションの重要な点は、どのタイプでも機能することです! – Jus12

+0

行数は100未満です。これはうまくいくようです。 – Jus12

2

はいこれが可能です。以下のような、それはすでに行われていますhttps://github.com/2ndQuadrant/mysqlcompat/blob/master/sql_bits/aggregate.sqlを見て:

-- 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

私の列が数値型を返すようにリンクされたコードは動作しません。 'function group_concat(数値)が存在しません。ヒント:指定された名前と引数の型に一致する関数はありません。明示的な型キャストを追加する必要があります。 – Jus12

+0

次に、実際にSQLを変更したくない場合は、数値のgroup_concat()集計を追加するか、SQLクエリの値をテキストにキャストしてください。 –

+0

SQLクエリはコンパイルされたコードであるため、変更することはオプションではありません。数値型を試します。私は本当にリンクの構文を理解していない。そこに何か参照がありますか? – Jus12

関連する問題