在此SQL语句中使用双重内部联接的原因是什么?


10

我正在看这个旧的SQL查询。我无法得到的一点是为什么它在同一列上两次内部连接同一表。我说的是Table1和Table1,别名为“ Table1Alias”,

SELECT DISTINCT othercolumns,
                Table1Alias.columna
FROM   maintable
       INNER JOIN secondarytable
               ON maintable.id1 = secondarytable.a_id1
       INNER JOIN table1
               ON secondarytable.id2 = table1.id3
       INNER JOIN table1 Table1Alias
               ON secondarytable.id2 = Table1Alias.id3
       INNER JOIN thirdtable
               ON table1.id4 = thirdtable.id5
       INNER JOIN fourthtable
               ON thirdtable.id6 = fourthtable.id7
       INNER JOIN fivetable
               ON thirdtable.id8 = fivetable.id9
       INNER JOIN sixthtable
               ON Table1Alias.columna = sixthtable.id10
       LEFT JOIN seventhtable
              ON thirdtable.id11 = seventhtable.id12
WHERE  LEFT(secondarytable.type123, 2) BETWEEN '01' AND '09'
       AND secondarytable.type456 = 'cate'
       AND table1.type = '0'
       AND Table1Alias.columna = 'conn'

Answers:


27

这样可能有助于重写查询,因此很明显两个联接是不同的,即联接是针对(同一表的)不同子集的:

FROM   maintable 
       INNER JOIN secondarytable 
               ON maintable.id1 = secondarytable.a_id1 
       INNER JOIN table1 
               ON secondarytable.id2 = table1.id3 
              AND table1.type = '0' 
       INNER JOIN table1 Table1Alias 
               ON secondarytable.id2 = Table1Alias.id3 
              AND Table1Alias.columna = 'conn' 
       INNER JOIN
       ...
WHERE  LEFT(secondarytable.type123, 2) BETWEEN '01' AND '09' 
       AND secondarytable.type456 = 'cate' 

不是在联接之后应用WHERE,即我同意那些约束是否是联接语句的一部分(即通过AND连接),但是所有经验中的WHERE都应用于联接的结果,以过滤出联接表,不影响实际联接。
Frank Hopkins

3
@Darkwing据我所知,放置条件并不重要,因为查询优化程序的工作是提出最佳执行计划。但是,最好将它们放在连接的旁边,因为这会使它们更易读,但这只是一种意见
Mathematics

即使在加入之后发生,加入的结果最终还是不同的。是的,连接的行通常会在连接之前进行过滤,因为这样可以提高性能。
Gherman '18

1
这也等同于加入子查询,例如INNER JOIN (SELECT * FROM table1 WHERE type = 0) table1。这可能使事情变得更加明显。
Barmar

3
@Mathematics-如果条件是在连接的ON子句中还是在该WHERE子句中,则如果连接是an,则关系重大OUTER JOIN。如果该ON子句中的条件失败,则仍然包括主行(没有匹配的外部行);如果在WHERE子句中失败,则将主行从结果集中排除。
RDFozz


2

在不了解表结构的情况下,该方法可能是利用较小的非覆盖索引,然后在较大的覆盖索引上加入表以获取剩余的行,从而避免执行“键查找”操作并避免修改现有索引(或者如果您不能修改索引)


2

每当一个表在一个复杂的联接中出现多次时,通常是因为有一个实体参与多个关系。从@Ypercube给出的答案来看,这里似乎是这种情况。

通常通过数据的语义以及与基础主题的连接来理解实体和关系。如果您的旧系统是精心构建的,则他们可能会采取一些措施来分析主题并仔细定义每个数据元素。他们甚至可能已经建立了实体关系模型。所有这些细心的工作可能都已经丢失了,您只能通过回顾过去来重构它。这有点像考古学。

对于像Table1这样的表名,我们对您的主题如何工作一无所知。即使名称是描述性的,我们对您系统主题的理解也可能与您的情况有很大不同。这将取决于您。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.