【问题标题】:Oracle SQL - reducing the number of selected attributes changes the resultOracle SQL - 减少选定属性的数量会改变结果
【发布时间】:2014-09-05 04:02:58
【问题描述】:

我只是在玩连接,发现了这个奇怪的问题:

我尝试过这样的事情:

SELECT *
  FROM ((EMPLOYEES INNER JOIN DEPARTMENTS USING(DEPARTMENT_ID))
  NATURAL JOIN LOCATIONS);

结果是 106 行。然后,我只想选择那些 CITY 属性等于 'Toronto' 的行,所以我这样做了:

SELECT *
  FROM ((EMPLOYEES INNER JOIN DEPARTMENTS USING(DEPARTMENT_ID))
  NATURAL JOIN LOCATIONS)
  WHERE CITY = 'Toronto';

结果正好包含我需要的 CITY 等于 'Toronto' 的 2 行。但是,我不需要所有列,所以我将查询更改为

SELECT LAST_NAME, JOB_ID, DEPARTMENT_ID, DEPARTMENT_NAME, CITY
  FROM ((EMPLOYEES INNER JOIN DEPARTMENTS USING(DEPARTMENT_ID))
  NATURAL JOIN LOCATIONS)
  WHERE CITY = 'Toronto';

这给了我 106 行,并且 CITY 始终设置为“多伦多”,这对我来说没有任何意义。另一个奇怪的事情是,当我也选择属性 LOCATION_ID 时,结果是正确的(我想要 2 行)。

以下是相关的关系模式:

describe EMPLOYEES
Name           Null     Type         
-------------- -------- ------------ 
EMPLOYEE_ID    NOT NULL NUMBER(6)    
FIRST_NAME              VARCHAR2(20)    
LAST_NAME      NOT NULL VARCHAR2(25)  
JOB_ID         NOT NULL VARCHAR2(10)
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)  

describe locations
Name           Null     Type         
-------------- -------- ------------ 
LOCATION_ID    NOT NULL NUMBER(4)    
CITY           NOT NULL VARCHAR2(30)

我知道我可以用 50 种不同且更简单的方式编写此查询,但我想知道这出了什么问题。我使用 Oracle SQL Developer。

谢谢

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    不知道出了什么问题,但不要使用自然连接。而是显式定义连接。自然连接会自动为您做事。编程时不是一件好事。

    SELECT LAST_NAME, JOB_ID, DEPARTMENT_ID, DEPARTMENT_NAME, CITY
    FROM EMPLOYEES INNER JOIN DEPARTMENTS USING(DEPARTMENT_ID)
    JOIN LOCATIONS ON (locations.location_id = departments.location_id)
    WHERE CITY = 'Toronto';
    
    Hartstein   MK_MAN  20  Marketing   Toronto
    Fay         MK_REP  20  Marketing   Toronto
    

    并且丢掉括号,它们很混乱,在这里毫无用处。

    编辑: 解释计划显示位置上有一个笛卡尔积。所以自然连接找不到连接条件,做一个笛卡尔积。 再一次:自然连接是邪恶的;-) 见:http://en.wikipedia.org/wiki/Join_(SQL)#Natural_join

    ---------------------------------------------------------------------------------------------
    | Id  | Operation                     | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT              |             |   106 |  4770 |     5   (0)| 00:00:01 |
    |   1 |  MERGE JOIN CARTESIAN         |             |   106 |  4770 |     5   (0)| 00:00:01 |
    |   2 |   MERGE JOIN                  |             |   106 |  3816 |     5   (0)| 00:00:01 |
    |   3 |    TABLE ACCESS BY INDEX ROWID| DEPARTMENTS |    27 |   432 |     2   (0)| 00:00:01 |
    |   4 |     INDEX FULL SCAN           | DEPT_ID_PK  |    27 |       |     1   (0)| 00:00:01 |
    |*  5 |    SORT JOIN                  |             |   107 |  2140 |     3   (0)| 00:00:01 |
    |   6 |     TABLE ACCESS FULL         | EMPLOYEES   |   107 |  2140 |     3   (0)| 00:00:01 |
    |   7 |   BUFFER SORT                 |             |     1 |     9 |     2   (0)| 00:00:01 |
    |*  8 |    INDEX RANGE SCAN           | LOC_CITY_IX |     1 |     9 |     0   (0)| 00:00:01 |
    ---------------------------------------------------------------------------------------------
    

    【讨论】:

      【解决方案2】:

      简短回答:不要使用NATURAL JOIN - 它只是自找麻烦(考虑有人重命名其中一个表中的列的情况)。

      长答案:

      这些查询可能返回不同结果的原因有几个:

      • 其中一个可能使用查询重写(如果存在符合条件的物化视图);检查两个查询的EXPLAIN PLAN
      • 您可能会遇到 Oracle 错误;你没有提到你正在运行的版本/补丁级别,所以很难说,请参阅下面的可能候选者的简短列表

      Wikipedia article about NATURAL JOIN mentioning they're dangerous

      WRONG RESULTS bug, referencing Metalink #406966.1

      Oracle forum discussion on buggy NATURAL JOINs

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-27
        • 2013-06-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-23
        相关资源
        最近更新 更多