-2

This is from Oracle Database 10g: SQL Fundamentals. Original Oracle textbook. Francly speaking, this all is actual so far.

There is a task which troubles me:

Display the last name, department name, and salary of any employee whose salary and commission match the salary and commission of many employee located in location ID 1700.

The topic to be learned is multiple column subqueries. This mean that we can't deviate from the offered model which is:

SELECT column, column, ...
FROM table
WHERE (column, column, ...) IN
(SELECT column, column, ...
FROM table
WHERE condition);

Well, my database:

describe employees
Name           Null     Type         
-------------- -------- ------------ 
EMPLOYEE_ID    NOT NULL NUMBER(6)    
FIRST_NAME              VARCHAR2(20) 
LAST_NAME      NOT NULL VARCHAR2(25) 
EMAIL          NOT NULL VARCHAR2(25) 
PHONE_NUMBER            VARCHAR2(20) 
HIRE_DATE      NOT NULL DATE         
JOB_ID         NOT NULL VARCHAR2(10) 
SALARY                  NUMBER(8,2)  
COMMISSION_PCT          NUMBER(2,2)  
MANAGER_ID              NUMBER(6)    
DEPARTMENT_ID           NUMBER(4)    

describe departments
Name            Null     Type         
--------------- -------- ------------ 
DEPARTMENT_ID   NOT NULL NUMBER(4)    
DEPARTMENT_NAME NOT NULL VARCHAR2(30) 
MANAGER_ID               NUMBER(6)    
LOCATION_ID              NUMBER(4)  

There is a solution:

select
  e.last_name,
  d.department_name, 
  e.salary
from employees e, departments d
where e.department_id = d.department_id
and (salary, nvl(commission_pct, 0)) in
  (select salary, nvl(commission_pct, 0)
   from employees e, departments d
   where e.department_id = d.department_id
   and d.location_id = 1700);

SELECTED 36 ROWS.

Well, I started checking. It seems that employees from location 1700 duplicated against themselves. Look: we take the whole list of employees and then juxtapose it with employees from location 1700. Of course, there will be duplicates.

I have prepared an excel file with some data (all employees, employees from location 1700, the result of my own desired result etc.). In the file it is more picturesque, with examples and so on. Please, have a look.

This is the file: https://skydrive.live.com/redir?resid=8CDFFBA921B002FE!150&authkey=!ADMRAE466BIunQM

Well, what I would like to do is to control that no employee is compared with themselves. This was my variant bevore I checked the solution.

select lnme, dpt, slry 
from
(
  select       
      employee_id eid,
      last_name lnme, 
      salary slry, 
      nvl(commission_pct,0) cpct,
      d.department_name dpt,
      location_id
  from employees e
  left join departments d
  on e.department_id = d.department_id
)
where (slry, cpct) in
(select 
    employee_id ide,
    salary slry, 
    nvl(commission_pct,0) cpct    
from employees e
join departments d
on e.department_id = d.department_id and location_id = 1700)
and ide <> eid

I wanted to make sure that no employee is compared with the same employee. But I failed.

Could you comment on all this situation: 1. Whether I'm completely wrong and the solution of Oracle is perfect. 2. If Oracle is wrong, could you help me with this code?

Thank you in advance.

4

1 回答 1

0

该问题要求您识别其薪水和佣金与部门 1700 中员工的薪水和薪水的任意组合匹配的任何员工。该问题并未说要从该部门排除员工。所以它们出现在结果集中是完全正确的。

“一个员工比不上自己。”

您不是在匹配员工,而是在匹配薪水。碰巧的是,目标工资列表是从部门 1700 的子查询中生成的:它可以很容易地成为 CSV 文件中的数字列表。


让我们做一个思想实验。部门 1700 有 3 名员工:

name       | salary  | comm
-----------+---------+-----
CHIP       |  10,100 |    0  
RUNCITER   |  12,200 |    0  
CONLEY     |  10,500 |    0  

公司里没有其他人的收入超过 10K。

那么这个问题的答案是什么:有多少员工的薪水和佣金与部门 1700 中任何员工的薪水和佣金相匹配?

然后乔得到了适度的加薪,薪水如下:

name       | salary  | comm
-----------+---------+-----
CHIP       |  10,500 |    0  
RUNCITER   |  12,200 |    0  
CONLEY     |  10,500 |    0  

那么现在同一个问题的答案是什么?

  1. 还是三个

在这两种情况下,答案都是“三”。

为什么?

因为 SQL 是一种基于集合的编程语言,所以在部门 1700 中获得确切工资和佣金的所有员工的集合必须包括在部门 1700 工作的所有员工。

有一个不同的集合,它是所有在部门 1700 中赚取确切工资和佣金的员工的集合,他们自己不在部门 1700 工作。但这不是 SQL 基础知识测验要寻找的集合。

于 2013-01-26T21:55:35.400 回答