2009-02-18 22 views
1

根据我在网上可以找到的少量证据,我最喜欢的postgres聚合之一是“list”,归因于“idocs中的Chris Rohlfs”。修改postgresql“list”聚合以删除重复项

CREATE FUNCTION comma_cat (text, text) 
    RETURNS text AS 
    'SELECT CASE 
    WHEN $2 is null or $2 = '''' THEN $1 
    WHEN $1 is null or $1 = '''' THEN $2 
    ELSE $1 || '', '' || $2 
    END' 
LANGUAGE sql; 

CREATE AGGREGATE list (BASETYPE = text, SFUNC = comma_cat, STYPE = text, INITCOND = ''); 

我发现,有时候我希望消除重复。 old mailing list thread暗示这种方法不能进行排序,这可能是一个重复删除的交易杀手。 Another post in the same thread建议一个功能,做同样的事情;也许它为此目的更易修改?

与此同时,我只是用另一种语言按摩输出。但是如果我们可以直接在postgres中做到这一点,那将会很酷!

+0

见更新后 – Quassnoi 2009-02-18 22:40:00

+0

从编辑感动:很遗憾,Quassnoi的原始方法似乎没有帮助;我从最初使用的方法中得到了新方法的结果列表。我曾尝试添加初始$ 1 = $ 2然后$ 1,尽管我不知道SORTOP。 – 2009-02-19 17:30:18

回答

3

可以使用中间阵列:

CREATE OR REPLACE FUNCTION comma_cat(text[], text) 
    RETURNS text[] AS 
$BODY$ 
    SELECT 
    CASE WHEN $1 @> ARRAY[$2] THEN $1 
    ELSE $1 || $2 
    END 
$BODY$ 
    LANGUAGE 'sql' VOLATILE; 

CREATE OR REPLACE FUNCTION comma_finish(text[]) 
    RETURNS text AS 
$BODY$ 
    SELECT array_to_string($1, ', ') 
$BODY$ 
    LANGUAGE 'sql' VOLATILE 
    COST 100; 

CREATE AGGREGATE list (BASETYPE = text, SFUNC = comma_cat, STYPE = text[], FINALFUNC = comma_finish, INITCOND = '{NULL, NULL}'); 

value id 
-------- -- 
"puer" 1 
"socer" 2 
"vesper" 3 
"vesper" 4 
"gener" 5 
"asper" 6 
"asper" 7 
"miser" 8 
"tener" 9 
"liber" 10 
"puer" 11 

SELECT list(value) 
FROM t_text 

"puer, vesper, gener, asper, miser, tener, liber, socer" 
+0

啊哈;现在这个工作,虽然我不得不删除COST 100,因为它给了我一个语法错误(postgresql 8.2.3)。万分感谢。现在我需要去找一个关于创建函数和聚集的好参考,这样我就能理解它在做什么了! – 2009-02-19 17:34:52

3

你可以把一个“独特的”预选赛聚合函数调用中删除重复:

select list(distinct <column>) 
from...