左连接和内连接组

时间:2017-03-23 07:02:57

标签: sql oracle join left-join inner-join

说,我有以下查询:

SELECT * FROM TABLE1 
    JOIN TABLE2 ON ...
    LEFT JOIN TABLE3 ON ...
        JOIN TABLE3_1 ON ...
        JOIN TABLE3_2 ON ...
        JOIN TABLE3_3 ON ...

我想要实现的是TABLE3,TABLE3_1,TABLE3_2,TABLE3_3内部连接(我只需要它们之间的所有匹配数据,其余的都没有)。然后对于TABLE1,TABLE2也有内部连接。但是从TABLE1 + TABLE2结果来看,有些人没有相应的TABLE3条目,没关系,我仍然会想要它。

如果按原样运行上面的伪代码,显然它不会达到相同的结果。

4 个答案:

答案 0 :(得分:8)

使用paretheses强制加入顺序,

SELECT * 
FROM (
   TABLE1 
   JOIN TABLE2 ON ...)
LEFT JOIN (
    TABLE3 
    JOIN TABLE3_1 ON ...
    JOIN TABLE3_2 ON ...
    JOIN TABLE3_3 ON ...) ON ...

答案 1 :(得分:2)

检查this answer

@Serg答案是正确的,但如果在语句末尾指定posts条件,则不需要使用括号。

ON

你这样改写:

SELECT * FROM TABLE1 
    JOIN TABLE2 ON ...
    LEFT JOIN TABLE3 ON ThisConditionShouldBeAtTheEnd
        JOIN TABLE3_1 ON ...
        JOIN TABLE3_2 ON ...
        JOIN TABLE3_3 ON ...

另见this article for more explanation。原因是JOIN条件从左到右(自上而下)进行评估,并且您需要在之前的内部连接之后评估LEFT连接条件。

答案 2 :(得分:1)

免责声明:我手头没有oracle DB可以检查,但希望它会包含一些帮助你的想法。

解决方案1:您可以使用括号来表示(TABLE3 x N)的中间连接表。伪代码:

select *
FROM TABLE1
    inner join TABLE2 on (condition)
    left join (
        table3
        inner join table3_1 on (condition)
        inner join table3_2 on (condition)
        inner join table3_3 on (condition)
    ) as table3_joined ON (table3_joined.ID = table2.id)

至少可以在MSSQL上运行。我无法验证它在oracle中是否有效,但您可以尝试。我认为这种语法非常明确,易于遵循/维护。

解决方案2:另一种方法是重复使用相同的从左到右的顺序,这种顺序会让您使用正确的连接来帮助您。伪代码:

select *
from table3
    inner join table3_1 on (condition)
    inner join table3_2 on (condition)
    inner join table3_3 on (condition)
    right join table2 on (condition)
    inner join table1 on (condition)

这种语法可能有效,但imho使用正确的连接会使语法更难以理解。

答案 3 :(得分:0)

其他答案的替代方案是CTE(公用表表达式)。这只是对内连接table3组的查询以及对内连接table1 / table 2组的查询,并且这两个组在主查询中是外连接的。对我来说(显然这是主观的)如果我在其他人的代码中遇到它,我会发现这更容易理解发生了什么。

WITH 
t3_group AS
 (SELECT * 
   FROM table3 ON ...
        INNER JOIN table3_1 ON ...
        INNER JOIN table3_2 ON ...
        INNER JOIN table3_3 ON ... ),
t1_t2_group AS
 (SELECT *
   FROM table1
        INNER JOIN table2 ON ...)
SELECT * 
  FROM t1_t2_group
       LEFT JOIN t3_group ON ...