【问题标题】:Grouping multiple rows into one string postgres for each position in select对于选择中的每个位置,将多行分组为一个字符串 postgres
【发布时间】: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 个是最相似的)。

这个语句应该是什么样子的?

【问题讨论】:

  • 样本数据和期望的结果真的很有帮助。

标签: sql postgresql aggregate aggregate-functions


【解决方案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 中使用数组而不是字符串。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-18
      • 1970-01-01
      • 1970-01-01
      • 2021-07-20
      • 1970-01-01
      • 2013-09-03
      • 1970-01-01
      • 2020-04-28
      相关资源
      最近更新 更多