为什么一个查询返回比其他查询更多

时间:2016-12-11 09:51:10

标签: sql oracle null subquery nvl

使用以下问题,您可以向我解释两个SQL之间的区别以及它们没有相同结果的原因吗?

显示工资和佣金与位于ID1700位置的员工的工资和佣金相匹配的任何员工的姓氏,部门名称和工资。

SELECT E.LAST_NAME, D.DEPARTMENT_NAME, E.SALARY
  FROM EMPLOYEES E
  JOIN DEPARTMENTS D
    ON (E.DEPARTMENT_ID =D.DEPARTMENT_ID)
  WHERE E.SALARY IN (SELECT SALARY
                       FROM EMPLOYEES
                       WHERE D.LOCATION_ID = 1700) AND
        E.COMMISSION_PCT IN (SELECT COMMISSION_PCT
                               FROM EMPLOYEES
                               WHERE D.LOCATION_ID = 1700);

(0输出)

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输出)

1 个答案:

答案 0 :(得分:2)

请注意此查询:

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

...将包括与位置1700中的某个人具有相同薪水和佣金的任何员工。因此,位置1700中的所有员工都将包含在结果集中。但是,如果只有位于1700位的人员具有完全相同的工资和佣金,那么也可以找到不在该位置的其他员工。因此,此查询可以正确回答给定的分配。

但是,另一个查询在两个子查询中都有一个奇怪的条件,因为它在外部查询(唯一定义D的地方)上应用条件 - 而不是子查询 - 它这样做了两次(没有帮助):

SELECT E.LAST_NAME, D.DEPARTMENT_NAME, E.SALARY
  FROM EMPLOYEES E
  JOIN DEPARTMENTS D
    ON (E.DEPARTMENT_ID =D.DEPARTMENT_ID)
  WHERE E.SALARY IN (SELECT SALARY
                       FROM EMPLOYEES
                       WHERE D.LOCATION_ID = 1700) AND
        E.COMMISSION_PCT IN (SELECT COMMISSION_PCT
                               FROM EMPLOYEES
                               WHERE D.LOCATION_ID = 1700);

如果要在外部location_id子句中的where上移动该条件,则不会更改任何实质内容。现在很明显,此查询 排除了 任何不在位置1700的员工 - 对于其他查询,情况并非总是如此。

此外,此问题没有NVL功能应用于commission_pct,这意味着如果员工nullcommission_pct,员工也会被排除在外。这是因为NULL IN (SELECT ...) 总是 评估为false。

因此,有两个原因可以解释为什么这个查询可以返回更少的记录,以及为什么它是你得到的任务的错误答案。