保留string_agg内部的不同顺序

时间:2016-03-03 14:18:23

标签: postgresql sql-order-by distinct aggregate recursive-query

我的SQL函数:

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”代表“国家公园”,这个城市包括两个城市:SãoGabrielda Cachoeira和Santa Isabel do Rio Negro。因此它出现了两次。

如果我更改了

的最后一行
select string_agg(nome,', ') from locpais

我得到了

  

“PARNA Pico da Neblina,PARNA Pico da Neblina,SãoGabrielda   Cachoeira,Santa Isabel do Rio Negro,RIO NEGRO,NORTE AMAZONENSE,   Amazonas,Norte,Brasil“

除了双“PARNA Pico da Neblina”之外几乎没有。所以我试过了:

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

但现在我得到了

  

“Amazonas,Brasil,Norte,NORTE AMAZONENSE,PARNA Pico da Neblina,RIO   NEGRO,Santa Isabel do Rio Negro,SãoGabrielda Cachoeira“

哪个是乱序的。我正在尝试在order by内添加string_agg,但无法使其正常工作。表格的定义是here

2 个答案:

答案 0 :(得分:3)

如您所知,如果您没有先按明确表达式排序,则无法合并DISTINCTORDER BY

但是可以使用像

这样的东西
array_to_string(arry_uniq_stable(array_agg(nome ORDER BY tid DESC)), ', ') 

在函数arry_uniq_stable的帮助下,删除数组中的重复项,而不是改变它的顺序,就像我在https://stackoverflow.com/a/42399297/5805552中给出了一个示例

请注意使用实际为您提供确定结果的ORDER BY表达式。根据您提供的示例,单独使用tid是不够的,因为存在具有不同nome的重复值(8)。

答案 1 :(得分:2)

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