如何 select 来自 Oracle 中另一个子查询的具有最大列的行
How to select the row with the max column from another subquery in Oracle
基本上我是想找到计数结果的最大值。这是一个例子:
期望输出:工作数量最多的员工姓名和完成的工作数量。
我的表(粗体表示主键,*表示外键):
员工 (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;
这 returns 每个员工的最大工作数,这是毫无意义的,因为子查询已经这样做了,这不是期望的结果。
查询#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;
这在我的情况下有点用,但不考虑多个员工具有相同的最大值。
有没有简单的方法来解决这个问题,显然不需要改变数据库布局,最好只使用子查询(我还是个初学者)?
首先,看起来您需要按 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
基本上我是想找到计数结果的最大值。这是一个例子:
期望输出:工作数量最多的员工姓名和完成的工作数量。
我的表(粗体表示主键,*表示外键):
员工 (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;
这 returns 每个员工的最大工作数,这是毫无意义的,因为子查询已经这样做了,这不是期望的结果。
查询#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;
这在我的情况下有点用,但不考虑多个员工具有相同的最大值。
有没有简单的方法来解决这个问题,显然不需要改变数据库布局,最好只使用子查询(我还是个初学者)?
首先,看起来您需要按 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