quarta-feira, 9 de março de 2011

Junções entre tabelas (JOINS)

Uma das dificuldades dos iniciantes na linguagem SQL é a construção de consultas utilizando junções entre tabelas, um recurso fundamental para visualizar os dados de um banco relacional.

Ao juntar as linhas de duas tabelas A e B, o SQL Server tenta combinar cada linha de A com todas as linhas de B, seguindo um critério estabelecido ao criar a junção (cláusula ON). Assim, serão retornadas todas as associações válidas da linha de A com as linhas de B, podendo haver mais do que uma correspondência em B para cada linha de A.

O resultado de uma junção pode ser utilizado para retornar os dados para um usuário ou aplicação,  mas também pode ser referenciado em uma consulta como uma nova tabela, permitindo que novas junções e filtros sejam realizados sobre este sub-resultado. Além disso, pode-se selecionar colunas específicas de cada tabela participante de uma junção ou mesmo não retornar colunas de uma tabela.

Para exemplificar, utilizaremos duas tabelas temporárias muito simples com apenas uma coluna do tipo inteiro em cada uma.

-- Criando tabela A
CREATE TABLE #a (id int)  

-- Criando tabela B
CREATE TABLE #b (id int)

E popularemos estas tabelas com alguns dados para testarmos as junções:

-- Populando tabela A
INSERT INTO #a VALUES (1)
INSERT INTO #a VALUES (2)

-- Populando tabela B
INSERT INTO #b VALUES (1)
INSERT INTO #b VALUES (3)

Desta forma, nossas tabelas para testes serão:

#A
#B
id id
1 1
2 3

Nos scripts de exemplo, utilizarei Alias para aumentar a legibilidade.

INNER JOIN

A junção mais utilizada para explorar os relacionamentos em tabelas é o INNER JOIN. Através desta junção, são retornadas todas as linhas das tabelas A e B que correspondam ao critério estabelecido na cláusula ON.

Podemos juntar os dados de nossas tabelas #a e #b utilizando o comando abaixo:

SELECT * FROM #a A
INNER JOIN #b B
   ON A.id = B.id

O resultado desta consulta está na figura abaixo:


Observe que o SQL Server retornou apenas as linhas que correspondem ao critério da cláusula ON.

LEFT JOIN

Um outro tipo de junção disponível na linguagem T-SQL é o LEFT JOIN. Ao juntar a tabela A com a tabela B utilizando o LEFT JOIN, todas as linhas de A serão retornadas, mesmo que não seja encontrada uma linha em B que atenda ao critério de alguma linha em A.

Se uma linha da tabela A não estiver associada a uma linha da tabela B e o resultado da consulta apresentar colunas da tabela B, estas colunas serão retornadas com o valor NULL para esta linha.

Abaixo, temos o comando para realizar um LEFT JOIN entre nossas tabelas de teste:

SELECT * FROM #a a
LEFT JOIN #b b
   ON a.id = b.id

Verifique o resultado da consulta na figura abaixo:


Observe que o SQL Server retornou todas as linhas da tabela A. Para a coluna pertencente à tabela B, só foram preenchidas com dados as linhas onde o critério definido na cláusula ON foi atendido.

Outro aspecto importante é a ordem das tabelas participantes do LEFT JOIN. Serão retornadas todas as linhas da primeira tabela, e apenas as linhas de B que atendam ao critério da junção.

RIGHT JOIN

O RIGHT JOIN é muito semelhante ao LEFT JOIN. A diferença fundamental é que serão retornadas todas as linhas da segunda tabela participante da junção.

O comando abaixo define uma consulta utilizando o RIGHT JOIN para juntar os dados de nossas tabelas de teste:

SELECT * FROM #a a
RIGHT JOIN #b b
   ON a.id = b.id

Veja o resultado:


Observe que o SQL Server retornou todas as linhas da tabela B. Para a coluna pertencente à tabela A, só foram preenchidas com dados as linhas onde o critério definido na cláusula ON foi atendido.

Assim como no LEFT JOIN, a ordem das tabelas participantes é importante e pode alterar o resultado de um RIGHT JOIN

FULL JOIN

O funcionamento do FULL JOIN pode ser considerado uma combinação do LEFT JOIN e o RIGHT JOIN, ou seja, quando se realiza uma junção entre duas tabelas A e B através do FULL JOIN, obtém-se como resultado uma combinação das linhas de A e B que respeitam a condição definida na cláusula ON e também farão parte do resultado as linhas de ambas as tabelas que não foram associadas.

Vejamos na prática. O comando abaixo realiza o FULL JOIN entre as tabelas que criamos para testar as junções:

SELECT * FROM #a a
FULL JOIN #b b
   ON a.id = b.id

A figura abaixo exibe o resultado deste comando:


CROSS JOIN

O CROSS JOIN diferencia-se dos outros tipos de junção, pois não permite que seja especificada uma condição para a junção (Cláusula ON). Assim, o resultado será uma combinação de TODAS as linhas da primeira tabela com TODAS as linhas da segunda tabela.

Esse é um dos tipos de junção menos utilizados, talvez pelo risco apresentado ao combinar duas tabelas com muitos registros ou mesmo por não permitir a criação de uma condição de junção, o que não é interessante para explorar dados relacionais.

O comando abaixo realiza o CROSS JOIN entre nossas tabelas de teste:

SELECT * FROM #a
CROSS JOIN #b

Observe que não há filtro. Define-se apenas quais tabelas participarão da junção. O resultado este comando é exibido na figura abaixo:


No resultado acima, verificamos que cada linha da tabela #a foi combinada com uma linha da tabela #b, não houve filtros ou restrições.

É preciso ter cuidado ao utilizar CROSS JOIN, pois devido à ausência de condições de junção, seu resultado pode apresentar um número muito grande de linhas (o número de linhas do resultado será sempre igual à multiplicação do número de linhas das tabelas participantes), o que pode causar impactos na performance do processamento, leitura e escrita em disco (I/O) e também gerar um grande tráfego na rede onde se localiza a instância do SQL Server.

SELF JOIN

Algumas pessoa costumam dar o nome de SELF JOIN para as junções onde uma tabela é associada a ela mesma. Todas as junções descritas acima podem ser utilizadas para realizar um SELF JOIN.

ALGUMAS DICAS...

  • Procure criar índices para os campos utilizados com frequencia para realizar junções, garantindo assim uma performance maior no processamento das junções.
  • Evite utilizar o CROSS JOIN. Ele pode impactar seriamente no desempenho de seu servidor SQL Server.

14 comentários:

Alessandro H. Garbiati disse...

Que massa, sobre o SELF JOIN e o OUTER JOIN, são referencias de se o JOIN é outra tabela(OUTER) ou ela mesma(SELF), podendo ser explicito ou não no SQL SERVER.
Parabéns, ganhou meu +

Anônimo disse...
Este comentário foi removido por um administrador do blog.
Anônimo disse...
Este comentário foi removido por um administrador do blog.
Anônimo disse...

oBRIGADA !!!

Anônimo disse...

olá. gostaria de saber como trazer somente o registro 2 da tabela A, visto que ele não possui relacionamento com a tabela B! Obrigado

Hercules Carlos disse...

gostaria que analizasse esse sql e me dissese pq nao da certo:
Select iv.cod_produto, sum(iv.vlr_total) as vlr_total, p.nome from itemvendas iv join produtos p on p.codigo = iv.cod_produto
group by iv.cod_produto

Evandro Junqueira Ramos disse...

Olá Hercules, qual o resultado esperado para essa consulta? Qual o erro obtido?

Francisco Araújo disse...

Excelente!

Marcos Alexandre Magalhaes Brandao disse...

Beleza!

Flavio David disse...

Valeu pela explicação ......


Equipe da Link Data Center



ABRÃOHITO HENRIQUE disse...

100%... Vlw msm... me salvou...

ABRÃOHITO HENRIQUE disse...

O MEU FICOU ASSIM...

SELECT A.ID, A.ATIVO, B.LOJA, A.NOME, A.CODIGO, A.ELIMINADO, A.ELIMINADOPOR, A.DT_ELIMINACAO
FROM PRODUTO A
INNER JOIN PRODUTO_ESTOQUE B
ON A.ID = B.ID_PRODUTO
where NOME like 'CARTAO%' and LOJA = 0

Wanderlan Lelis disse...

Muito bom, parabéns.

Anathol Vidrigo disse...

E POSSIVEL JUNTAR UMA STORED PROCEDURE COM UMA TABELA?

Postar um comentário