Inner加入3个或更多表如何工作?

时间:2015-07-31 16:54:16

标签: sql inner-join

我看到了一些关于这个问题的问题,但坦率地说我并不太了解。

我想要的是:我有五个表,我想返回一个选择,主表与其他4的所有交叉点。我正在做2个选择,然后是UNION。它工作得很好,但我想我可以通过一次选择来提高性能。

以下是我的代码示例:

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

关于表格。

A 与所有其他表共享column1

(int) column1

B C 具有与以下相同的结构:

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

D E 也具有相同的结构:

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

正如我们所看到的,除了表 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

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

2 个答案:

答案 0 :(得分:2)

您始终可以使用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)上的索引。

答案 1 :(得分:1)

这应该可以满足您的需求。但是,我不知道表现会更好。

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

上查看