2016-11-10 71 views
1

我想,我可能有一个误解,多连接如何在多个表上工作。假设你有三张表A,B,C,你需要加入他们。内连接多个表

这里是V1

SELECT A.NAME AS name1 
    ,B.NAME AS name2 
    ,C.NAME AS name3 
FROM A 
INNER JOIN B 
    ON A.id = B.id 
INNER JOIN C 
    ON B.id = C.id 

这里是V2

SELECT A.NAME AS name1 
    ,D.NAME AS name2 
    ,D.NAME AS name3 
FROM A 
INNER JOIN (
    SELECT B.NAME AS name2 
     ,C.NAME AS name3 
    FROM B 
    INNER JOIN C 
     ON B.id = C.id 
    ) AS D 
    ON A.id = D.id 

是否有这两个版本之间的性能差异? 尽管第一个查询看起来更清晰,但我需要构建一个查询生成器UI,将联接限制为只有2个表有所帮助。

+0

那么,作为第一个,第二个查询将失败,因为你没有选择内部查询中的'Id'。但更重要的是,这些不是同一个查询。在第一个中,你将'A'与'B'和'A'与'C'联系起来。第二,你将'B'关联到'C',这在第一个查询中不是定义的关系。不仅如此,第二个版本更难以阅读/理解。你应该坚持第一个版本 - 它更干净,更易于理解。 – Siyual

+0

@Siyual - 两个连接中隐含的B到C关系 - 不会加入B ON A.id = B.id JOIN C ON A.id = C.id给出与JOIN B ON相同的结果A.id = B.id JOIN C ON B.id = C.id – PaulF

+0

@PaulF在这种情况下,推断B到C关系的唯一方法是如果您加入了“ID”字段中的表对于所有三个(这与他的例子一样,尽管这看起来像虚拟代码,而不是他实际使用的)。 *但是,我非常怀疑你需要在三个表中进行连接,每个表的主键都是相同的。如果是这样的话,那么是的,你可以推断B到C的关系。但除此之外,你无法建立连接。 – Siyual

回答

1

一般来说,子查询的一个问题是,它可能需要RDBMS创建一个临时表来完成子查询 - 并且在一个足够大的表上这可能是一个严重的开销 - 并且可能不能使用任何索引子查询优化查询,然后扫描表。

当然,DDL和表的大小不包括在内,所以最好的方法是让Postgres解释它计划做什么和比较/对比。