【问题标题】:ORACLE: multiple column subqueriesORACLE:多列子查询
【发布时间】:2013-01-26 19:31:15
【问题描述】:

这是来自 Oracle 数据库 10g:SQL 基础。 原始的 Oracle 教科书。 从法语上讲,到目前为止,这一切都是真实的。

有一个任务让我很困扰:

显示工资和佣金与位置 ID 1700 中许多员工的工资和佣金相匹配的任何员工的姓氏、部门名称和工资。

要学习的主题是多列子查询。这意味着我们不能偏离所提供的模型:

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

好吧,我的数据库:

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)  

有一个解决办法:

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);

选择了 36 行。

好吧,我开始检查了。似乎来自位置 1700 的员工与自己重复。 看:我们获取整个员工列表,然后将其与位置 1700 的员工并列。当然,会有重复。

我已经准备了一个包含一些数据的 excel 文件(所有员工、来自位置 1700 的员工、我自己想要的结果等)。在文件中它更加风景如画,并附有示例等。请看一看。

这是文件:https://skydrive.live.com/redir?resid=8CDFFBA921B002FE!150&authkey=!ADMRAE466BIunQM

嗯,我想做的是控制没有员工与自己进行比较。 这是我在检查解决方案之前的变体。

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

我想确保没有员工与同一员工进行比较。但我失败了。

您能否对所有这些情况发表评论: 1.我是否完全错了,Oracle的解决方案是否完美。 2.如果Oracle错了,你能帮我写这段代码吗?

提前谢谢你。

【问题讨论】:

    标签: oracle select subquery


    【解决方案1】:

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

    “一个员工无法匹配自己。”

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


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

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

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

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

    1. 三个

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

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

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

    1. 还是三个
    2. 两个

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

    为什么?

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

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

    【讨论】:

    • 英语不是我的母语。但!我查阅了牛津词典。 oald8.oxfordlearnersdictionaries.com/dictionary/match_2 “如果两件事匹配或如果一件事匹配另一件事,它们是相同或非常相似的”。一名员工无法匹配自己。从逻辑上讲,即使没有牛津,它也会很笨拙。不,事实并非如此。
    • @Pepperwork:如果您不想列出 1700 部门的员工,那么只需在最外面的查询中这样说:... AND e.department_id != 1700
    • @Jonathan Leffler,我希望他们中的一些人在场。如果来自 1700 的员工在同一地点有另一位同事并获得适当的薪酬,则他们必须都在选择中。但没有一个员工没有任何匹配。
    • @Pepperwork - 这是一个不同的问题。这可能是一个合法的编程问题,但它不是您发布的问题。
    • 在现实世界中,如果您有一个发现不准确的要求,那么您可以要求更明确的说明。但这是一本书的练习,所以虽然你发现可能缺乏精确性是件好事,但你不能问作者。既然您认为有两种方法可以理解问题,请对这两种方法都进行回答,并为您学到的东西感到高兴。
    猜你喜欢
    • 2019-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多