Oracle SQL查询:为员工获得最大销售额
我想为我的每个员工找到最大的销售额(并显示员工的姓名)。在MySQL中,它非常简单:Oracle SQL查询:为员工获得最大销售额,sql,oracle,plsql,Sql,Oracle,Plsql,我想为我的每个员工找到最大的销售额(并显示员工的姓名)。在MySQL中,它非常简单: select * from employee, sale where employee.id = sale.employee_id group by employee_id order by sale.total desc 这与人们所期望的差不多,它将返回一个员工列表,并最终返回员工行中最大的销售记录 但是,在使用GROUPBY子句时,Oracle不允许返回非GROUPBY表达式的列。
select *
from employee, sale
where employee.id = sale.employee_id
group by employee_id
order by sale.total desc
这与人们所期望的差不多,它将返回一个员工列表,并最终返回员工行中最大的销售记录
但是,在使用GROUPBY子句时,Oracle不允许返回非GROUPBY表达式的列。这是否使我在MySQL中所做的事情在Oracle中变得“不可能”?还是有解决办法?我想我可以执行某种类型的子查询,但不确定是否有其他方法可以执行此操作,但构造起来不会太复杂。要获得最大销售额,可以使用group by和
max
函数
select e.name, max (s.total)
from employee e, sale s
where e.id = s.employee_id
group by e.name
order by s.total desc
- 我假设员工姓名在
表的employee
列中。我还为employee表和sales表添加了别名name
- 如果您希望查看员工的总销售额,可以将
替换为max()
sum()
选择*
并用你需要的列替换它,然后按所有“未处理”列分组
你最终会得到这样的结果:
select employee.id, employee.name, max(sale.total)
from employee, sale
where employee.id = sale.employee_id
group by employee.id, employee.name
order by max(sale.total) desc
这是一件痛苦的事——我以前已经做过很多次了——但只要通过将所有相关列添加到您的组中即可祝贺您,您已经学会了足够危险的东西 你真正想要的是每位员工最大的销售额。现在,在MySQL中,按销售额对它们进行排序,然后对它们进行分组是可行的,尽管根据ANSI SQL,这是不合法的。(基本上,MySQL是任意地为每个员工抓取第一行,这“起作用”是因为排序。) 做这件事的正确方法不是依赖于做你想做的事情的副作用;相反,你应该明确要求你想要什么:每个员工的最大销售额。在SQL中,这是:
select employee.id, max( sale.total)
from employee, sale
where employee.id = sale.employee_id
group by employee.id
order by 2
如果您想选择销售额最高的员工,您根本不需要在此处按
分组
您只需选择最高销售额并将其加入到员工中即可:
SELECT *
FROM (
SELECT sale.*, ROW_NUMBER() OVER (ORDER BY total DESC) AS rn
FROM sale
) s
JOIN employee e
ON e.id = s.employee_id
AND s.rn = 1
这将选择总销售额最高的单行
如果要选择每个员工的最高销售额,只需在查询中添加一个partitionby
子句:
SELECT *
FROM (
SELECT sale.*, ROW_NUMBER() OVER (PARTITION BY employee_id ORDER BY total DESC) AS rn
FROM sale
) s
JOIN employee e
ON e.id = s.employee_id
AND s.rn = 1
您在查询中所做的是滥用MySQL
语法糖,它允许您在分组查询中选择一个随机的未分组值。所选行不保证是最高销售额。正如文档中所述:使用此功能时,每个组中的所有行对于按部分从组中写入的列应具有相同的值。服务器可以从组中自由返回任何值,因此结果是不确定的,除非所有值都相同。哦,嗯,我想max是我想要的,但是如何获得名称呢?保存此信息的表/列名是什么?*是为了简洁。在我的非示例中,我实际上指定了列。然而,我确实感到非常恼火,因为我需要在GROUPBY子句中包含我要选择的每一列。所以,抓取12列会将我的SQL语句变成一些看起来可笑的怪物。但是,关于max的观点是很好的。很抱歉*
。你不可能总是从一个随机的网络帖子中知道这个家伙是在骂还是真的在执行它。我也了解这个怪物。由于“好奇”的数据库设计,我不得不在一个分组中最多包含12列。这很令人不快。嗯,在一个地址表中可以很容易地得到多达12列。Addr1,Addr2,City,State,Zip,Country,Long,Lat-这只是基本字段。