博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
解析一道笔试题目:查找各个部门工资最高的前3名员工信息
阅读量:4040 次
发布时间:2019-05-24

本文共 6875 字,大约阅读时间需要 22 分钟。

解析一道笔试题目:查找各个部门工资最高的前3名员工信息

一张员工表(tab_employee)和一张部门表(tab_department)的样例数据如下所示:

SQL>SQL> select * from tab_employee;        ID NAME           SALARY DEPARTMENTID---------- ---------- ---------- ------------         1 Joe             70000            1         2 Henry           80000            2         3 Sam             60000            2         4 Max             90000            1         5 Randy           85000            1已用时间:  00: 00: 00.01SQL> select * from tab_department;        ID NAME---------- ----------         1 IT         2 Sales已用时间:  00: 00: 00.00SQL>

要求编写一条查询语句,查找各个部门中工资最高的前3名员工。

解析:

创建两种数据表和准备测试数据如下:

CREATE TABLE tab_Employee

  (
    Id           NUMBER(4),
    Name         VARCHAR2(50),
    Salary       NUMBER(7,2),
    DepartmentId NUMBER(4)
  );
CREATE TABLE tab_Department
  (Id NUMBER(4), Name VARCHAR2(50)
  );

insert into tab_Employee (Id, Name, Salary, DepartmentId) values ('1', 'Joe', '70000', '1');

insert into tab_Employee (Id, Name, Salary, DepartmentId) values ('2', 'Henry', '80000', '2');
insert into tab_Employee (Id, Name, Salary, DepartmentId) values ('3', 'Sam', '60000', '2');
insert into tab_Employee (Id, Name, Salary, DepartmentId) values ('4', 'Max', '90000', '1');
insert into tab_Employee (Id, Name, Salary, DepartmentId) values ('5', 'Randy', '85000', '1');
insert into tab_Employee (Id, Name, Salary, DepartmentId) values ('6', 'Janet', '69000', '1');

insert into tab_Department (Id, Name) values ('1', 'IT');

insert into tab_Department (Id, Name) values ('2', 'Sales');

commit;

解答的SQL语句如下:

SELECT a.DEPARTMENT AS Department,

  a.EMPLOYEE        AS Employee,
  a.SALARY          AS Salary
FROM
  (SELECT d.name AS DEPARTMENT,
    e.NAME       AS EMPLOYEE,
    e.SALARY,
    ROW_NUMBER() OVER(PARTITION BY d.name ORDER BY e.Salary DESC) AS rn
  FROM tab_EMPLOYEE e
  LEFT JOIN tab_DEPARTMENT d
  ON e.DepartmentId = d.Id
  ) a
WHERE rn <= 3

SQL>SQL> SELECT a.DEPARTMENT AS Department,  2    a.EMPLOYEE        AS Employee,  3    a.SALARY          AS Salary  4  FROM  5    (SELECT d.name AS DEPARTMENT,  6      e.NAME       AS EMPLOYEE,  7      e.SALARY,  8      ROW_NUMBER() OVER(PARTITION BY d.name ORDER BY e.Salary DESC) AS rn  9    FROM tab_EMPLOYEE e 10    LEFT JOIN tab_DEPARTMENT d 11    ON e.DepartmentId = d.Id 12    ) a 13  WHERE rn <= 3;DEPARTMENT EMPLOYEE       SALARY---------- ---------- ----------IT         Max             90000IT         Randy           85000IT         Joe             70000Sales      Henry           80000Sales      Sam             60000已用时间:  00: 00: 00.01

解答到这里,看似问题已经解决了,但是如果插入下面两行数据,结果还是这样吗?

插入两条测试数据:

SQL>SQL> insert into tab_Employee (Id, Name, Salary, DepartmentId) values ('7', 'Bean', '', '1');已创建 1 行。已用时间:  00: 00: 00.00SQL> insert into tab_Employee (Id, Name, Salary, DepartmentId) values ('8', 'Mason', '', '2');已创建 1 行。已用时间:  00: 00: 00.00SQL> commit;

即部门1和部门2中各有一名员工,工资(Salary)的值为null。

执行查询后发现结果为:

SQL>SQL> SELECT a.DEPARTMENT AS Department,  2    a.EMPLOYEE        AS Employee,  3    a.SALARY          AS Salary  4  FROM  5    (SELECT d.name AS DEPARTMENT,  6      e.NAME       AS EMPLOYEE,  7      e.SALARY,  8      ROW_NUMBER() OVER(PARTITION BY d.name ORDER BY e.Salary DESC) AS rn  9    FROM tab_EMPLOYEE e 10    LEFT JOIN tab_DEPARTMENT d 11    ON e.DepartmentId = d.Id 12    ) a 13  WHERE rn <= 3;DEPARTMENT EMPLOYEE       SALARY---------- ---------- ----------IT         BeanIT         Max             90000IT         Randy           85000Sales      MasonSales      Henry           80000Sales      Sam             60000已选择 6 行。已用时间:  00: 00: 00.02SQL>

我们发现查询结果已经与开始的查询要求不相符了。

说明上面的SQL语句不能通过测试!!!对于Salary为null值的情况没有进行处理。

下面的查询仍然存在问题:

SQL> SELECT b.name AS department,  2    a.name      AS employee,  3    a.salary  4  FROM  5    (SELECT id,  6      name,  7      salary,  8      departmentid,  9      dense_rank() over (partition BY departmentid order by salary DESC) AS rank 10    FROM tab_employee 11    ) a 12  INNER JOIN tab_department b 13  ON a.departmentid = b.id 14  WHERE rank       IN (1,2,3);DEPARTMENT EMPLOYEE       SALARY---------- ---------- ----------IT         BeanIT         Max             90000IT         Randy           85000Sales      MasonSales      Henry           80000Sales      Sam             60000已选择 6 行。已用时间:  00: 00: 00.07

 

 

问题拓展:如果改变一下要求:查询各个部门中工资最高的员工(即工资最高的第1名)

SELECT D.name Department,

  E1.Name   AS Employee,
  E1.Salary AS Salary
FROM tab_Employee E1
JOIN tab_Department D
on E1.DepartmentId = D.Id
AND E1.Salary        >=
  (SELECT MAX(Salary)
  FROM tab_Employee E2
  WHERE E1.DepartmentId = E2.DepartmentId
  );

SQL>SQL> SELECT D.name Department,  2    E1.Name   AS Employee,  3    E1.Salary AS Salary  4  FROM tab_Employee E1  5  JOIN tab_Department D  6  on E1.DepartmentId = D.Id  7  AND E1.Salary        >=  8    (SELECT MAX(Salary)  9    FROM tab_Employee E2 10    WHERE E1.DepartmentId = E2.DepartmentId 11    );DEPARTMENT EMPLOYEE       SALARY---------- ---------- ----------Sales      Henry           80000IT         Max             90000已用时间:  00: 00: 00.12SQL>

下面的查询语句:

SELECT d.Name AS Department,  t.Name      AS Employee,  t.Salary    AS SalaryFROM  (SELECT Id,    DepartmentId,    Name,    Salary,    DENSE_RANK() Over (Partition BY DepartmentId order by Salary DESC) AS Rank  FROM tab_Employee  )  tINNER JOIN tab_Department dON t.DepartmentId = d.IdWHERE t.Rank     <= 3;
SQL>SQL> SELECT d.Name AS Department,  2    t.Name      AS Employee,  3    t.Salary    AS Salary  4  FROM  5    (SELECT Id,  6      DepartmentId,  7      Name,  8      Salary,  9      DENSE_RANK() Over (Partition BY DepartmentId order by Salary DESC) AS Rank 10    FROM tab_Employee  )  t 11  INNER JOIN tab_Department d 12  ON t.DepartmentId = d.Id 13  WHERE t.Rank     <= 3;DEPARTMENT EMPLOYEE       SALARY---------- ---------- ----------IT         BeanIT         Max             90000IT         Randy           85000Sales      MasonSales      Henry           80000Sales      Sam             60000已选择 6 行。已用时间:  00: 00: 00.10SQL>

又一种写法:

SELECT d.Name AS "Department",  a.Name      AS "Employee",  Salary      AS "Salary"FROM tab_Department dJOIN  (SELECT Name,    Salary,    DepartmentId,    DENSE_RANK() OVER (PARTITION BY DepartmentId ORDER BY Salary DESC) AS ranks  FROM tab_Employee  ) aON d.Id       =a.DepartmentIdWHERE a.ranks<=3ORDER BY d.Name,  Salary DESC,  a.Name
SQL>SQL> SELECT d.Name AS "Department",  2    a.Name      AS "Employee",  3    Salary      AS "Salary"  4  FROM tab_Department d  5  JOIN  6    (SELECT Name,  7      Salary,  8      DepartmentId,  9      DENSE_RANK() OVER (PARTITION BY DepartmentId ORDER BY Salary DESC) AS ranks 10    FROM tab_Employee 11    ) a 12  ON d.Id       =a.DepartmentId 13  WHERE a.ranks<=3 14  ORDER BY d.Name, 15    Salary DESC, 16    a.Name;Department Employee       Salary---------- ---------- ----------IT         BeanIT         Max             90000IT         Randy           85000Sales      MasonSales      Henry           80000Sales      Sam             60000已选择 6 行。已用时间:  00: 00: 00.01

 

转载地址:http://kftdi.baihongyu.com/

你可能感兴趣的文章
[Mac]Mac 操作系统 常见技巧
查看>>
苹果Swift编程语言入门教程【中文版】
查看>>
捕鱼忍者(ninja fishing)之游戏指南+游戏攻略+游戏体验
查看>>
iphone开发基础之objective-c学习
查看>>
iphone开发之SDK研究(待续)
查看>>
计算机网络复习要点
查看>>
Variable property attributes or Modifiers in iOS
查看>>
NSNotificationCenter 用法总结
查看>>
C primer plus 基础总结(一)
查看>>
剑指offer算法题分析与整理(一)
查看>>
剑指offer算法题分析与整理(三)
查看>>
Ubuntu 13.10使用fcitx输入法
查看>>
pidgin-lwqq 安装
查看>>
mint/ubuntu安装搜狗输入法
查看>>
C++动态申请数组和参数传递问题
查看>>
opencv学习——在MFC中读取和显示图像
查看>>
retext出现Could not parse file contents, check if you have the necessary module installed解决方案
查看>>
pyQt不同窗体间的值传递(一)——对话框关闭时返回值给主窗口
查看>>
linux mint下使用外部SMTP(如网易yeah.net)发邮件
查看>>
北京联通华为光猫HG8346R破解改桥接
查看>>