如何从Oracle中的另一个子查询中选择具有最大列的行

Posted

技术标签:

【中文标题】如何从Oracle中的另一个子查询中选择具有最大列的行【英文标题】:How to select the row with the max column from another subquery in Oracle 【发布时间】:2021-12-31 13:19:41 【问题描述】:

基本上,我试图找到计数结果的最大值。这是一个例子:

期望的输出:工作数量最多的员工的姓名和完成的工作数量。

我的表(粗体表示主键,*表示外键):

员工(Id、employee_name、....)

网站(Site_id、Site_name、....)

工作(Site_id*、Id*、DateJ)

这是我尝试过的两件事:

查询 #1:

Select 
    employee_name, 
    max(jobs_done) max_jobs
from 
    Employees E,
    (select 
         id, 
         count(*) jobs_done from jobs
     from jobs
     group by id) t
where 
    E.id = t.Id
group by 
    employee_name;

这将返回每个员工的最大工作量,这是毫无意义的,因为子查询已经这样做了,这不是预期的结果。

查询 #2:

Select 
    employee_name,
    t.job_done
from
    Employees E
    (Select 
         id, 
         count(*) job_done
     from Jobs
     group by id) t
where 
    E.id = t.id
order by 
    jobs_done desc
fetch first row only;

这有点适用于我的情况,但不适用于具有相同最大值的多个员工。

有没有一种简单的方法来解决这个问题,显然不改变数据库布局,最好只使用子查询(我还是个初学者)?

【问题讨论】:

也许您需要with ties 而不是only @astentx 这确实有效。如果其他人想贡献更多,我会继续发帖。谢谢你! 同一个employee_name可以有不同的ID吗? @SayanMalakshinov 是的,他们可以,因为 ID 是主键。 【参考方案1】:

首先,看起来您需要按Employee.ID 而非Employee_name 聚合,因为作业是通过ID 链接的,而不是employee_name。所以最好将聚合和Top-N推入子查询到Jobs。尽管Oracle 有一个特殊的查询转换机制Group-By Pushdown(甚至还有一个特殊的提示gby_pushdown),但最好让自己的查询更清晰、更可预测,不要依赖CBO(Oracle Optimizer)魔法。 其次,我建议至少对初学者使用 ANSI 连接语法,因为它更清晰一些。

所以它应该是这样的:

Select 
    e.id,
    e.employee_name,
    j.jobs_done
from
    (Select 
         id, 
         count(*) jobs_done
     from Jobs
     group by id
     order by jobs_done desc
     fetch first 1 row with ties
    ) j
    join Employees e
        on e.id = j.id
;

如您所见,j 子查询通过employee.id 聚合作业并仅获得前1 个with ties,然后我们只需加入Employee 即可获得Employee_name

【讨论】:

以上是关于如何从Oracle中的另一个子查询中选择具有最大列的行的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 2012 Express 如何从一列中提取信息并将其与具有表达式限制的另一列进行比较

仅当值存在于 SQL 的另一列中时,如何选择列的值?

如何从位于访问中的另一个子窗体中的组合框中过滤子窗体?

MySQL - 如何将子查询中的列别名用于另一个子查询?

Laravel - 查询构建器以选择具有唯一列值的多行(具有另一列的最大值)

CodeIgniter 查询:如何将列值移动到同一行中的另一列并将当前时间保存在原始列中?