首页 文章

左连接和内连接组

提问于
浏览
3

说,我有以下查询:

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

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

    Solution 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中是否有效,但您可以尝试 . 我认为这种语法非常明确,易于遵循/维护 .

    Solution2: 另一种方法是重复使用相同的从左到右的顺序,使用正确的连接可以帮助您获得优势 . 伪代码:

    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使用正确的连接会使语法更难以理解 .

  • 2

    使用paretheses强制连接顺序,种类

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

    检查this answer .

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

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

    你重写如下:

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

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

  • 8

    其他答案的替代方案是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 ...
    

相关问题