2

我在 Oracle 中有一个表,如下所示

   CREATE TABLE Employees(EmpId INT, 
                          EmpName VARCHAR2(30), 
                          Designation VARCHAR2(30), 
                          Salary INT);

我在表格中插入了如下行

INSERT ALL 
   INTO Employees(EmpId, EmpName, Designation, Salary)VALUES(101, 'Scott', 'Clerk', 2500)
   INTO Employees(EmpId, EmpName, Designation, Salary)VALUES(102, 'Mac', 'Manager', 5000)
   INTO Employees(EmpId, EmpName, Designation, Salary)VALUES(103, 'Steave', 'Clerk', 1500)
   INTO Employees(EmpId, EmpName, Designation, Salary)VALUES(104, 'John', 'Clerk', 1500)
   INTO Employees(EmpId, EmpName, Designation, Salary)VALUES(105, 'Jack', 'Analyst', 2500)
   INTO Employees(EmpId, EmpName, Designation, Salary)VALUES(106, 'Paul', 'Manager', 4500)
   INTO Employees(EmpId, EmpName, Designation, Salary)VALUES(107, 'Ryan', 'Clerk', 1250)
   INTO Employees(EmpId, EmpName, Designation, Salary)VALUES(108, 'Phillipe', 'Analyst', 3150)
   INTO Employees(EmpId, EmpName, Designation, Salary)VALUES(109, 'Clark', 'Clerk', 1200)
   INTO Employees(EmpId, EmpName, Designation, Salary)VALUES(110, 'Arnold', 'Clerk', 1100)
   SELECT * FROM dual;

以下是表格的简短概述

在此处输入图像描述

现在我想按以下名称分组收入最高的人

EmpName   Designation  Salary
Phillipe  Analyst      3150 
Scott     Clerk        2500
Mac       Manager      5000

我想要 empName、Designation 和 max Salary by designation。

我尝试了以下查询,但它带来了所有记录

SELECT EmpName, Designation, max(Salary) AS msal
  FROM Employees
 GROUP BY Designation, EmpName 
 ORDER BY Designation, msal DESC

谢谢您的回复

4

3 回答 3

3

具有相关子查询的版本

SELECT EmpName, Designation, Salary
  FROM Employees e
 WHERE Salary = (SELECT MAX(Salary) 
                   FROM Employees 
                  WHERE Designation = e.Designation)

或与JOIN

SELECT e.EmpName, e.Designation, e.Salary
  FROM Employees e JOIN 
(
  SELECT Designation, MAX(Salary) Salary
    FROM Employees 
   GROUP BY Designation
) q ON e.Designation = q.Designation
   AND e.Salary = q.Salary

这是两个查询的SQLFiddle演示

于 2013-07-04T07:14:45.843 回答
2
SELECT 
  max(EmpName) keep (dense_rank last order by salary) AS EmpName
, Designation
, max(Salary) keep (dense_rank last order by salary)  AS Salary
FROM Employees
GROUP BY Designation
;
于 2013-07-04T07:12:51.573 回答
2

假设您的意思是“指定”而不是“部门”,您可以使用分析查询来做到这一点:

SELECT EmpName, Designation, Salary
FROM (
    SELECT EmpName, Designation, Salary,
        RANK() OVER (PARTITION BY Designation ORDER BY Salary DESC) AS rn
      FROM Employees
)
WHERE rn = 1
ORDER BY Designation;

EMPNAME                        DESIGNATION                        SALARY
------------------------------ ------------------------------ ----------
Phillipe                       Analyst                              3150 
Scott                          Clerk                                2500 
Mac                            Manager                              5000 

内部查询对每一行应用排名,1 代表每个指定中的最高薪水(并允许平局)。然后,外部查询将结果重新限制为仅显示每个指定的排名最高的行。

在您的原始版本中,您group by实际上并没有做任何事情,因为它包括所有列有效 - 除了 empid,但这并没有什么不同,除非您有两个同名的人。您需要找到指定的最大值,然后找到与该最大值匹配的记录,这意味着查看同一张表;例如:

SELECT EmpName, Designation, Salary
  FROM Employees
 WHERE (Designation, Salary) IN (
     SELECT Designation, MAX(Salary)
       FROM Employees
      GROUP BY Designation
  )
ORDER BY Designation;

...或peterm的相关子查询;但我更喜欢分析路线,特别是对于较大的表格,因为您只打了一次表格。我个人觉得它更清楚。

于 2013-07-04T07:13:16.583 回答