【问题标题】:In PostgreSQL, return rows with unique values of one column based on the minimum value of another在 PostgreSQL 中,根据另一列的最小值返回具有唯一值的行
【发布时间】:2021-07-28 05:58:26
【问题描述】:

背景

我有这个 PostgreSQL 加入对我来说相当很好:

select  m.id,
        m.zodiac_sign,
        m.favorite_color,
        m.state,
        c.combined_id
from people."People" m
LEFT JOIN people.person_to_person_composite_crosstable c on m.id = c.id

如您所见,我正在加入两个表以引入 combined_id,我需要稍后在别处进行分析。

目标

我想编写一个查询,方法是选择combined_id,它旁边有m.id 的最低值(以及其他变量)。这应该会产生一个新表,其唯一/不同值为 combined_id

问题

问题是当前查询返回约 300 条记录,但我需要它返回约 100 条记录。为什么?每个combined_id 平均有3 个不同的m.id。我实际上并不关心m.id's;我关心获得一个独特的combined_id。因此,我决定一个好的“选择标准”是根据最低值 m.id 为具有相同 combined_id 的行选择行。

我的尝试

我已经查阅了几篇关于此的帖子,我觉得我已经很接近了。参见例如this onethis oneThis other one 正是我需要的(用MAX 而不是MIN),但他在 Unix Bash 中要求它????

这是我尝试过的一个例子:

select  m.id,
        m.zodiac_sign,
        m.favorite_color,
        m.state,
        c.combined_id
from people."People" m
LEFT JOIN people.person_to_person_composite_crosstable c on m.id = c.id
WHERE m.id IN (select min(m.id))

这会返回错误ERROR: aggregate functions are not allowed in WHERE

有什么想法吗?

【问题讨论】:

    标签: sql postgresql join


    【解决方案1】:

    Postgres 的 DISTINCT ON 可能是这里最好的方法:

    SELECT DISTINCT ON (c.combined_id)
        m.id,
        m.zodiac_sign,
        m.favorite_color,
        m.state,
        c.combined_id
    FROM people."People" m
    LEFT JOIN people.person_to_person_composite_crosstable c
        ON m.id = c.id
    ORDER BY
        c.combined_id,
        m.id;
    

    在性能方面,交叉表上的以下索引可能会加快查询速度:

    CREATE INDEX idx ON people.person_to_person_composite_crosstable (id, combined_id);
    

    如果使用,上面的索引应该让连接发生得更快。请注意,我涵盖了 combined_id 列,这是 select 所需的。

    【讨论】:

    • 点击刷新速度如此之快,我使用了您的初稿,它有 SELECT DISTINCT ON (m.id) 而不是 combined_id,它产生了相同的约 300 行 ? 新版本完美运行。我尝试了SELECT DISTINCT 的变体,但没有碰到SELECT DISTINCT ON。它是 Postgres 独有的吗?
    • @logjammin 是的...DISTINCT ON 完全是 Postgres 独有的,尽管其他一些数据库也有类似的东西(例如 SQL Server)。顺便说一句,我的答案的第二次编辑实际上与您在问题中所要求的相符。但我已经恢复,因为第一个版本似乎是你真正想要的。
    • 哦,等等,不,不要回复——也许我的问题搞砸了,但你拥有的第二个版本 (SELECT DISTINCT ON (c.combined_id)) 是我需要的版本,因为我想要一张带有独特 @ 的桌子987654331@'s,以及旁边出现的 m.id 都可以。
    猜你喜欢
    • 2014-02-04
    • 2021-10-16
    • 2018-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多