保留 distinct 内部的顺序 string_agg
Preserve the order of distinct inside string_agg
我的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" 代表 "National Park",这个涵盖两个城市:São Gabriel da Cachoeira 和 Santa Isabel do Rio Negro。因此它出现了两次。
如果我更改最后一行
select string_agg(nome,', ') from locpais
我明白了
"PARNA Pico da Neblina, PARNA Pico da Neblina, São Gabriel da
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ão Gabriel da Cachoeira"
这是错误的。我正在尝试在 string_agg
中添加一个 order by
,但无法使其工作。表的定义给出了.
select string_agg(nome,', ')
from (
select distinct nome
from locpais
order by tid desc
) s
如您所知,如果您不先按不同的表达式排序,则无法组合 DISTINCT
和 ORDER BY
:
两者都没有合计:
也不在SELECT:
The DISTINCT ON expression(s) must match the leftmost ORDER BY expression(s).
但是可以使用
array_to_string(arry_uniq_stable(array_agg(nome ORDER BY tid DESC)), ', ')
借助函数 arry_uniq_stable
删除数组中的重复项 w/o 改变它的顺序,就像我在
中给出的示例
请注意使用实际为您提供确定性结果的 ORDER BY
表达式。对于您给出的示例,仅 tid
是不够的,因为存在具有不同 nome
.
的重复值 (8)
我的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" 代表 "National Park",这个涵盖两个城市:São Gabriel da Cachoeira 和 Santa Isabel do Rio Negro。因此它出现了两次。
如果我更改最后一行
select string_agg(nome,', ') from locpais
我明白了
"PARNA Pico da Neblina, PARNA Pico da Neblina, São Gabriel da 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ão Gabriel da Cachoeira"
这是错误的。我正在尝试在 string_agg
中添加一个 order by
,但无法使其工作。表的定义给出了
select string_agg(nome,', ')
from (
select distinct nome
from locpais
order by tid desc
) s
如您所知,如果您不先按不同的表达式排序,则无法组合 DISTINCT
和 ORDER BY
:
两者都没有合计:
也不在SELECT:
The DISTINCT ON expression(s) must match the leftmost ORDER BY expression(s).
但是可以使用
array_to_string(arry_uniq_stable(array_agg(nome ORDER BY tid DESC)), ', ')
借助函数 arry_uniq_stable
删除数组中的重复项 w/o 改变它的顺序,就像我在
请注意使用实际为您提供确定性结果的 ORDER BY
表达式。对于您给出的示例,仅 tid
是不够的,因为存在具有不同 nome
.