内部连接 ​​3 个或更多表如何工作?

How does Inner join 3 or more tables works?

我看到了一些关于这个主题的问题,但坦白说我不太明白。

我想要什么:我有五个 table,我想 return 一个 select 与主要 table 与其他 4 个的所有交叉点。我我目前正在做 2 selects,然后是 UNION。它工作得很好,但我想我可以在单个 select.

中提高性能

这是我的代码示例:

SELECT column1 FROM tableA A
INNER JOIN table B ON A.column1 = B.column1
LEFT JOIN table D ON A.column1 = D.column1
LEFT JOIN table E A.column1 = E.column1
WHERE B.column2 IS NOT NULL
AND B.column3 = '7'
AND ( (D.column2 = 'x' OR D.column3 = 'y') OR (E.column2 = 'x' OR E.column3 = 'y') )

UNION

SELECT column1 FROM tableA A
INNER JOIN table C ON A.column1 = C.column1
LEFT JOIN table D ON A.column1 = D.column1
LEFT JOIN table E A.column1 = E.column1
WHERE C.column2 IS NOT NULL
AND C.column3 = '7'
AND ( (D.otherColumn2= 'x' OR D.otherColumn3 = 'y') OR (E.otherColumn2 = 'x' OR E.otherColumn3 = 'y') )

关于 tables.

Table A 与所有其他 table 共享 column1

(int) column1

Tables BC结构相同如下:

(int) column1 | (int) column2 | (varchar) column3

和tables DE也有相同的结构:

(int) column1 | (varchar) otherColumn2 | (varchar) otherColumn3

正如我们所见,两个 select 几乎相同,除了 table B C.

我在没有完整代码的情况下问了这个问题,@Kevin 解决了它。但是有了这些额外的信息,并尝试按照他的例子,我将代码更改为:

SELECT column1 FROM tableA A
LEFT JOIN table B ON (A.column1 = B.column1
    AND C.column2 IS NOT NULL
    AND C.column3 = '7')
LEFT JOIN table C ON (A.column1 = C.column1
    AND C.column2 IS NOT NULL
    AND C.column3 = '7')
LEFT JOIN table D ON A.column1 = D.column1
    AND (D.otherColumn2 = 'x' OR D.otherColumn3 = 'y')
LEFT JOIN table E A.column1 = E.column1
    AND (E.otherColumn2 = 'x' OR E.otherColumn3 = 'y')
WHERE
    B.column1 is not null
    or c.column1 is not null
    or D.column1 is not null
    or E.column1 is not null

但是我得到了很多额外的结果。我希望我在这里说清楚了,如果没有,请告诉我,我会更新这个问题。

这应该可以满足您的需求。不过,我不知道性能会好到什么地步。

SELECT A.column1 FROM tableA A
    LEFT JOIN tableB B ON A.column1 = B.column1
        AND B.column2 IS NOT NULL
        AND B.column3 = '7' 
    LEFT JOIN tableD d ON b.column1 = D.column1
    LEFT JOIN tableE e ON B.column1 = E.column1
    LEFT JOIN tableC C ON A.column1 = C.column1
        AND C.column2 IS NOT NULL
        AND C.column3 = '7'
    LEFT JOIN tableD d2 ON c.column1 = d2.column1
    LEFT JOIN tableE e2 ON c.column1 = e2.column1
    WHERE (B.column1 is not null 
           and (d.othercolumn2 = 'x' or d.othercolumn3='y' or e.othercolumn2 = 'x' or e.othercolumn3='y')
           )
           or (c.column1 is not null
               and (d2.othercolumn2 = 'x' or d2.othercolumn3='y' or e2.othercolumn2 = 'x' or e2.othercolumn3='y')
           )

您可以在sqlfiddle

上查看

您可以随时使用 exists:

select a.*
from tablea a
where exists (select 1 from tableb b where a.column1 = b.column1 and b.column3 = 7) or
      exists (select 1 from tablec c where a.column1 = c.column1 and c.column3 = 7);

当您使用 join 时,您 运行 有获得重复行的风险 -- 然后您可能会做额外的工作来删除重复项。 exists.

都是不必要的

而且,为了提高性能,您需要在 tableb(column1, column3)tablec(column1, column3) 上建立索引。