对于选择中的每个位置,将多行分组为一个字符串 postgres
Posted
技术标签:
【中文标题】对于选择中的每个位置,将多行分组为一个字符串 postgres【英文标题】:Grouping multiple rows into one string postgres for each position in select 【发布时间】:2020-03-06 03:41:37 【问题描述】:我有一个表education
,其中有一列university
。对于表中的每一行,我想从表中找到 3 所最相似的大学。
这是我的查询,可以找到与给定输入最相似的 3 所大学:
select distinct(university),
similarity(unaccent(lower(university)),
unaccent(lower('Boston university')))
from education
order by similarity(unaccent(lower(university)),
unaccent(lower('Boston university'))) desc
limit 3;
它工作正常。但是现在我想修改这个查询,以便为表中的每个现有大学获得两列和一行:第一列是大学名称,第二列是数据库中找到的三所最相似的大学(或如果它更容易 - 四个列,第一个是大学,接下来的 3 个是最相似的)。
这个语句应该是什么样子的?
【问题讨论】:
样本数据和期望的结果真的很有帮助。 【参考方案1】:您可以使用内联聚合查询:
with u as (select distinct university from education)
select
university,
(
select string_agg(u.university, ',')
from u
where u.university != e.university
order by similarity(
unaccent(lower(u.university)),
unaccent(lower(e.university))
) desc
limit 3
) similar_universities
from education e
这假设给定的大学可能在教育表中出现不止一次(因此需要 cte)。
【讨论】:
【参考方案2】:我认为横向连接和聚合可以满足您的需求:
select e.university, e2.universities
from education e cross join lateral
(select array_agg(university order by sim desc) as universities
from (select e2.university,
similarity(unaccent(lower(e2.university)),
unaccent(lower(e.university))
) as sim
from education e2
order by sim desc
limit 3
) e2
) e2;
注意:最相似的大学可能是同名大学。 (您可以在子查询中使用 where
子句将其过滤掉。)
这会将值作为数组返回,因为我更喜欢在 Postgres 中使用数组而不是字符串。
【讨论】:
以上是关于对于选择中的每个位置,将多行分组为一个字符串 postgres的主要内容,如果未能解决你的问题,请参考以下文章