Qual é o motivo do uso de junção interna dupla nesta instrução SQL?


10

Eu estou olhando para esta consulta SQL herdada. O pouco que não consigo entender é por que é interno juntando a mesma tabela duas vezes nas mesmas colunas. Eu estou falando sobre Table1 e Table1 juntou-se ao alias "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'

Respostas:


27

Pode ajudar a reescrever a consulta assim, portanto, é óbvio que as 2 junções são diferentes , ou seja, as junções são para subconjuntos diferentes (da mesma tabela):

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' 

não é o WHERE a ser aplicado APÓS as junções, ou seja, eu concordaria se essas restrições fizessem parte da declaração de junção, ou seja, conectadas por um AND, mas WHERE em toda a experiência é aplicada ao resultado da junção que filtra as linhas de a tabela unida, sem influenciar a junção real.
22818 Frank Hopkins

3
@ Darkwing Até onde eu sei, não importa onde você coloca as condições, pois o trabalho do otimizador de consultas é apresentar o melhor plano de exceção. No entanto, é melhor colocá-los ao lado da junta, uma vez que os torna mais legível, mas é apenas uma opinião
Matemática

Mesmo que isso aconteça APÓS a junção, os resultados das junções são diferentes no final. E sim, as linhas unidas geralmente são filtradas antes da associação, pois melhoram o desempenho.
Gherman

11
Também é equivalente a se juntar a uma subconsulta, por exemplo INNER JOIN (SELECT * FROM table1 WHERE type = 0) table1. Isso pode tornar ainda mais óbvio o que está acontecendo.
Barmar

3
@ Matemática - se uma condição está na ONcláusula de uma junção ou na WHEREcláusula pode ter grande importância se a junção for um OUTER JOIN. Se uma condição falhar na ONcláusula, a linha principal ainda será incluída (sem uma linha externa correspondente); se falhar na WHEREcláusula, a linha principal será excluída do conjunto de resultados.
RDFozz

8

Observando a wherecláusula, a linha apontada por table1requer a coluna type= '0' e a linha apontada por table1aliasrequer a coluna columna= 'conn'.

Talvez haja várias linhas table1para o mesmo id3?


2

Sem ver a estrutura da tabela - a abordagem poderia ser a utilização de um índice menor de cobertura e, em seguida, ingressar na tabela em um índice de cobertura maior para obter o restante das linhas para evitar uma operação de 'Key Lookup' e para modificar os índices existentes. (ou se você não pode modificar os índices)


2

Sempre que uma tabela aparece mais de uma vez em uma associação complexa, geralmente ocorre porque existe uma entidade que participa de mais de um relacionamento. Parece ser esse o caso aqui, a julgar pela resposta que o @Ypercube deu.

Entidades e relacionamentos são geralmente entendidos através da semântica dos dados e da conexão com o assunto subjacente. Se o seu sistema legado foi cuidadosamente construído, eles provavelmente tomaram alguns cuidados para analisar o assunto e definir cuidadosamente cada um dos elementos de dados. Eles podem até ter construído um modelo de Entidade-Relacionamento. Todo esse trabalho cuidadoso pode ter sido perdido, e você não consegue reconstruí-lo cavando o passado. Isto é um pouco como arqueologia.

Com nomes de tabelas como Tabela1, não temos idéia de como o assunto funciona. E mesmo que os nomes sejam descritivos, nosso entendimento do assunto do seu sistema pode ser muito diferente do necessário no seu caso. Vai depender de você.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.