2016-03-03 96 views
1

我的SQL函数:保留不同的内部string_agg的顺序

with recursive locpais as (
    select l.id, l.nome, l.tipo tid, lp.pai 
    from loc l 
    left join locpai lp on lp.loc = l.id 
    where l.id = 12554 
    union 
    select l.id, l.nome, l.tipo tid, lp.pai 
    from loc l 
    left join locpai lp on lp.loc = l.id 
    join locpais p on (l.id = p.pai) 
) 
select * from locpais 

给我

12554 |  PARNA Pico da Neblina | 9 | 1564 
12554 |  PARNA Pico da Neblina | 9 | 1547 
1547 | São Gabriel da Cachoeira | 8 | 1400 
1564 | Santa Isabel do Rio Negro | 8 | 1400 
1400 |     RIO NEGRO | 7 | 908 
    908 |   NORTE AMAZONENSE | 6 | 234 
    234 |     Amazonas | 5 | 229 
    229 |      Norte | 4 | 30 
    30 |     Brasil | 3 | 

这是地方的层次结构。 “PARNA”代表“国家公园”,这一个涵盖两个城市:圣加布里埃尔卡库埃拉和圣伊莎贝尔做里约黑人。因此它出现两次。

如果我更改

select string_agg(nome,', ') from locpais 

最后一行我得到

“PARNA内布利纳峰,PARNA内布利纳峰,圣盖博DA 卡舒埃拉,圣伊莎贝尔杜里奥内格罗,RIO NEGRO,NORTE AMAZONENSE, Amazonas,Norte,Brasil“

这几乎没有问题,除了双”PARN Pico da Neblina“。所以,我想:

select string_agg(distinct nome, ', ') from locpais 

,但现在我得到

“亚马孙,巴西,北,北AMAZONENSE,PARNA内布利纳峰,RIO 黑人圣伊莎贝尔杜里奥内格罗,圣加布里埃尔达卡绍埃拉“

这是坏的。我试图在string_agg内添加一个order by,但无法使其正常工作。表格的定义给出了here

+0

http://stackoverflow.com/a/10470738/248343? 'array_to_string' +'array_agg'而不是'string_agg' – OcuS

+0

@OcuS“从locpais中选择array_to_string(array_agg(不同于nid order by tid desc),',')但它给出了”与DISTINCT集合在一起“,ORDER BY表达式必须出现在参数列表中“,我不确定它的含义。 – Rodrigo

回答

1
select string_agg(nome,', ') 
from (
    select distinct nome 
    from locpais 
    order by tid desc 
) s 
1

当你找到了,你不能结合DISTINCTORDER BY如果不通过不同的表达首先命令:

但是可以使用类似

array_to_string(arry_uniq_stable(array_agg(nome ORDER BY tid DESC)), ', ') 

与函数arry_uniq_stable的帮助下,在一个阵列删除重复W/O改变它的顺序就像我在https://stackoverflow.com/a/42399297/5805552的示例

请注意使用ORDER BY表达式,该表达式实际上会为您提供确定性结果。通过您给出的示例,单独使用tid是不够的,因为重复值(8)与nome不同。