当查询返回多个 min(count) 数据时,如何从不同表中选择所有行

Posted

技术标签:

【中文标题】当查询返回多个 min(count) 数据时,如何从不同表中选择所有行【英文标题】:How can I select all rows from different tables when the query returns multiple min(count) data 【发布时间】:2021-01-08 00:03:09 【问题描述】:

考虑我创建了下表,并且根据 ER 图创建了关系。

我被要求找出哪些项目的员工人数最少。我尝试使用下面的代码,但我只得到 1 个输出,而我希望根据输入的数据创建两条记录:

select pname from project p where pnumber = (select min(count) from (select count(*) from works_on group by pno)t)

下表是数据:

员工表:

项目表:

Works_On 表:

【问题讨论】:

【参考方案1】:

Postgres 13(当前为 RC)中,使用新的 WITH TIES 变得非常简单:

SELECT pno
FROM   works_on
GROUP  BY 1
ORDER  BY count(*)
FETCH  FIRST 1 ROWS WITH TIES;  -- new & hot

如果您需要更多项目属性,请加入表project单独从works_on 中以廉价的方式识别“获胜”项目编号。这是最快的。

SELECT p.*
FROM  (
   SELECT pno AS pnumber
   FROM   works_on
   GROUP  BY 1
   ORDER  BY count(*)
   FETCH  FIRST 1 ROWS WITH TIES
   ) w
JOIN  project p USING (pnumber);

相关:

Get apps with the highest review count since a dynamic series of days

【讨论】:

【参考方案2】:

我会推荐聚合和窗口函数。

逻辑是统计每个项目的员工人数,然后使用窗口函数对项目进行排名。 ran() 很方便,因为它允许绑定:

select *
from (
    select p.*, count(*) cnt_employees, rank() over(order by count(*)) rn
    from project p
    inner join works_on wo on wo.pno = p.pnumber
    group by p.pno
) t
where rn = 1

【讨论】:

以上是关于当查询返回多个 min(count) 数据时,如何从不同表中选择所有行的主要内容,如果未能解决你的问题,请参考以下文章

在 postgresql 中使用 MIN, MAX, (SUM/COUNT) 子查询

聚合函数查询

【MySQL】分组查询(GROUP BY)

不匹配时仍然返回 JOIN 结果

为啥 OleDb ExecuteScalar 方法在查询 COUNT 时返回 Decimal?

带有 HAVING 子句的 SQL 查询的 COUNT 个结果