0

我试图从表中选择 2 个值,员工 emp_name,emp_location 按 emp_location 分组,我知道按函数分组的列需要在 select 子句中,但我想知道是否有任何其他方法可以获得这些值在单个查询中。

我的意图是根据年龄在每个地点只选择一名员工。样本查询

select emp_name,emp_location 
from Employee 
where emp_age=25 
group by emp_location

请在这方面提供帮助。

非常感谢所有回答这个问题的人。我将尝试学习这些 windows 功能,因为它们非常方便。

4

3 回答 3

2

ORA-00979 不是 Group By 函数错误

子句中只允许在子句中指定的聚合函数列。GROUP BYSELECT

在这方面,Oracle 严格遵循 SQL 标准。但是,正如您在评论中注意到的那样,在这一点上,其他一些 RDBMS 不如 Oracle 严格。例如,引用MySQL 的文档(强调我的):

MySQL 扩展了 GROUP BY 的使用,以便选择列表可以引用未在 GROUP BY 子句中命名的非聚合列。[...]

但是,这主要在每个未在 GROUP BY 中命名的非聚合列中的所有值对于每个组都相同时很有用。服务器可以从每个组中自由选择任何值,因此除非它们相同,否则选择的值是不确定的

因此,在推荐的用例中,将额外的列添加到GROUP BY子句将导致相同的结果。


select emp_name,emp_location 
--     ^^^^^^^^
--   this is *not* part of the ̀`GROUP BY` clause
from Employee 
where emp_state=25 
group by emp_location

也许您正在寻找:

...
group by emp_location, emp_name
于 2015-01-01T11:21:30.700 回答
2

这在 MySQL 而不是 Oracle 中起作用的原因是,在 Oracle 以及大多数其他数据库中,您要么需要在group by子句中指定一个字段(或表达式),要么它必须是一个结合了以下值的聚合组中的所有值合并为一个。例如,这将起作用:

select max(emp_name),emp_location 
from Employee 
where emp_age=25 
group by emp_location

但是,它可能不是最好的解决方案。如果您只想要名称,它会起作用,但是当您想要为员工提供多个字段时,您会遇到麻烦。在这种情况下max不会成功。在下面的查询中,您可能会得到与姓氏不匹配的名字。

select max(emp_firstname), max(emp_lastname), emp_location 
from Employee 
where emp_age=25 
group by emp_location 

对此的解决方案是使用窗口函数(分析函数)。有了这些,您可以为每条记录生成一个值,而无需立即减少记录数。例如,使用窗口max函数,您可以为名为 的人选择最大年龄John,并在结果中的每个 John 旁边显示该值,即使他们没有那个年龄。

一些函数,如和 ,rank可用于为每个员工生成一个编号,然后您可以使用该编号进行过滤。在下面的示例中,我为每个位置(按分区)创建了一个计数器,并按此例中的名称和 ID 排序。您也可以指定其他字段,例如,如果您希望每个位置每个年龄一个名称,您可以在 中同时指定年龄和位置。如果您想要每个位置的最年长员工,您可以删除and代替。dense_rankrow_numberpartition bywhere emp_age=25order by emp_age desc

select
  *
from
  (select 
    emp_name, emp_location,
    dense_rank() over (partition by emp_location order by emp_name, emp_id) as emp_rank
  from Employee 
  where emp_age=25)
where
  emp_rank = 1
于 2015-01-01T11:52:16.487 回答
0
select emp_name,emp_location
from Employee
where emp_age=25
group by emp_name,emp_location

或者

select max(emp_name) emp_name,emp_location
from Employee
where emp_age=25
group by emp_location 
于 2015-01-01T11:44:05.897 回答