Executar junções usando o Access SQL

Em um sistema de banco de dados relacional como o Access, é frequentemente necessário extrair informações de mais de uma tabela de cada vez. Isso pode ser realizado através do uso de uma instrução JOIN do SQL, que permite recuperar registros de tabelas com relações definidas, sejam elas de um-para-um, de um-para-muitos ou de muitos para muitos.

INNER JOINs

A INNER JOIN, também conhecida como uma junção equivalente, é o tipo de junção mais comum. Essa junção é usada para recuperar linhas de duas ou mais tabelas, fazendo a correspondência com um valor de campo comum entre tabelas. Os campos para os quais você faz a junção devem ter tipos de dados semelhantes, e você não pode fazer a junção em tipos de dados MEMO ou OLEOBJECT.

Para criar uma instrução INNER JOIN, use as palavras-chave INNER JOIN na cláusula FROM de uma instrução SELECT.

Este exemplo usa a INNER JOIN para criar um conjunto de resultados de todos os clientes que têm faturas, além de datas e valores das faturas.

SELECT [Last Name], InvoiceDate, Amount 
   FROM tblCustomers INNER JOIN tblInvoices 
   ON tblCustomers.CustomerID=tblInvoices.CustomerID 
   ORDER BY InvoiceDate 

Lembre-se de que os nomes de tabelas estão divididos pelas palavras-chave INNER JOIN e que a comparação relacional é após a palavra-chave ON. Para as comparações relacionais, você também pode usar os <operadores , , >=<, >=ou<>, e também pode usar a palavra-chave BETWEEN. Observe também os campos de ID de ambas as tabelas são usados apenas na comparação relacional. Eles não fazem parte do conjunto de resultados final.

Para qualificar ainda mais a instrução SELECT, você pode usar uma cláusula WHERE após a comparação de junção na cláusula ON.

O exemplo a seguir restringe o conjunto de resultados para incluir apenas faturas com data após 1º de janeiro de 1998.

SELECT [Last Name], InvoiceDate, Amount 
   FROM tblCustomers INNER JOIN tblInvoices 
   ON tblCustomers.CustomerID=tblInvoices.CustomerID 
   WHERE tblInvoices.InvoiceDate > #01/01/1998# 
   ORDER BY InvoiceDate 

Quando você deve fazer a junção de mais de uma tabela, pode aninhar as cláusulas INNER JOIN. O exemplo a seguir cria uma instrução SELECT para criar o conjunto de resultados, mas também inclui as informações de cidade e estado de cada cliente, adicionando a junção INNER JOIN à tabela tblShipping.

SELECT [Last Name], InvoiceDate, Amount, City, State 
   FROM (tblCustomers INNER JOIN tblInvoices 
   ON tblCustomers.CustomerID=tblInvoices.CustomerID) 
      INNER JOIN tblShipping 
      ON tblCustomers.CustomerID=tblShipping.CustomerID 
   ORDER BY InvoiceDate 

Lembre-se que a primeira cláusula JOIN fica entre parênteses para mantê-la logicamente separada da segunda cláusula JOIN. Também é possível unir uma tabela a si mesmo usando um alias para o segundo nome da tabela na cláusula FROM . Suponha que você queira encontrar todos os registros de clientes que têm sobrenomes duplicados. Você pode fazer isso criando o alias "A" para a segunda tabela e verificando se há nomes diferentes.

SELECT tblCustomers.[Last Name], 
   tblCustomers.[First Name] 
   FROM tblCustomers INNER JOIN tblCustomers AS A 
   ON tblCustomers.[Last Name]=A.[Last Name] 
   WHERE tblCustomers.[First Name]<>A.[First Name] 
   ORDER BY tblCustomers.[Last Name] 

OUTER JOINs

Uma OUTER JOIN é usada para recuperar os registros de várias tabelas, preservando os registros de uma das tabelas, mesmo se não houver nenhum registro correspondente na outra tabela. Há dois tipos de OUTER JOINs aos quais o o mecanismo de banco de dados do Access dá suporte: LEFT OUTER JOINs e RIGHT OUTER JOINs.

Pense em duas tabelas que estão lado a lado, uma tabela à esquerda e outra à direita. O LEFT OUTER JOIN seleciona todas as linhas na tabela à direita que correspondem aos critérios de comparação relacional e também seleciona todas as linhas da tabela esquerda, mesmo que nenhuma correspondência exista na tabela direita. A RIGHT OUTER JOIN é apenas o inverso da LEFT OUTER JOIN. Todas as linhas da tabela direita são preservadas em vez disso.

Digamos, por exemplo, que você deseja determinar o valor total da nota fiscal de cada cliente, mas quando um cliente não tem nota fiscal, você quer mostrá-lo exibindo a palavra "Nenhuma".

SELECT [Last Name] & ', ' &  [First Name] AS Name, 
   IIF(Sum(Amount) IS NULL,'NONE',Sum(Amount)) AS Total 
   FROM tblCustomers LEFT OUTER JOIN tblInvoices 
   ON tblCustomers.CustomerID=tblInvoices.CustomerID 
   GROUP BY [Last Name] & ', ' &  [First Name] 

Várias ações são executadas na instrução SQL anterior. A primeira é o uso do operador de concatenação de cadeia de caracteres "&". Essa operador permite fazer a junção de dois ou mais campos como uma cadeia de caracteres. A segunda é a instrução if (IIf) imediata, que verifica se o total é nulo. Se for, a instrução retornará a palavra "NONE". Se o total não for nulo, o valor será retornado. Por último, há a cláusula OUTER JOIN. O uso do LEFT OUTER JOIN preserva as linhas na tabela à esquerda para que você veja todos os clientes, mesmo aqueles que não têm faturas.

OUTER JOINs podem ser aninhadas dentro de INNER JOINs em uma junção de várias tabelas, mas INNER JOINs não podem ser aninhadas dentro de OUTER JOINs.

O produto cartesiano

Produto cartesiano é um termo que surge frequentemente nas discussões sobre junção. Um produto Cartesiano é definido como "todas as combinações possíveis de todas as linhas em todas as tabelas". Por exemplo, se você ingressar em duas tabelas sem qualquer tipo de qualificação ou tipo de junção, obterá um produto Cartesian.

SELECT * 
   FROM tblCustomers, tblInvoices 

Não é uma situação ideal, principalmente com as tabelas que contêm centenas ou milhares de linhas. Convém evitar a criação de produtos cartesianos, qualificando sempre as junções.

O operador UNION

Embora o operador UNION, também conhecido como uma consulta de união, não seja considerado tecnicamente uma junção, é incluído aqui porque envolve dados combinados de diversas fontes de dados em um conjunto de resultados, que é similar a alguns tipos de junções. O operador UNION é usado para unir dados de tabelas, instruções SELECT ou consultas, deixando de fora as linhas duplicadas. Ambas as fontes de dados devem ter o mesmo número de campos, mas os campos não precisam ser do mesmo tipo de dados. Suponha que você tenha uma tabela de Funcionários com a mesma estrutura que a tabela Clientes e queira criar uma lista de nomes e endereços de email combinando ambas as tabelas.

SELECT [Last Name], [First Name], Email 
   FROM tblCustomers 
UNION 
SELECT [Last Name], [First Name], Email 
   FROM tblEmployees 

Para recuperar todos os campos de ambas as tabelas, você pode usar a palavra-chave TABLE, da maneira a seguir.

TABLE tblCustomers 
UNION 
TABLE tblEmployees 

O operador UNION não exibirá os registros que sejam duplicatas exatas em ambas as tabelas, mas ele pode ser substituído pelo uso do predicado ALL, após a palavra-chave UNION da seguinte maneira:

SELECT [Last Name], [First Name], Email 
   FROM tblCustomers 
UNION ALL 
SELECT [Last Name], [First Name], Email 
   FROM tblEmployees 

A instrução TRANSFORM

Embora seja também conhecida como uma consulta de tabela de referência cruzada, a instrução TRANSFORM não é considerada tecnicamente uma junção, ela é incluída aqui porque envolve dados combinados de diversas fontes de dados em um conjunto de resultados, que é similar a alguns tipos de junções.

A instrução TRANSFORM é usada para calcular a soma, média, contagem ou outro tipo de total agregado nos registros. Em seguida, ela exibe as informações em um formato de grade ou planilha, com os dados agrupados na horizontal (linhas) e na vertical (colunas). A forma geral de uma instrução TRANSFORM é a seguinte.

   TRANSFORM aggregating function 
   SELECT statement 
   PIVOT column heading field 

Como exemplo de cenário, você pode criar uma planilha de dados que exibe os totais anuais das notas fiscais de cada cliente. Os títulos verticais serão os nomes dos clientes e os títulos horizontais serão os anos. Você pode modificar uma instrução SQL anterior para se ajustar à instrução transform.

TRANSFORM 
IIF(Sum([Amount]) IS NULL,'NONE',Sum([Amount])) 
   AS Total 
SELECT [Last Name] & ', ' & [First Name] AS Name 
      FROM tblCustomers LEFT JOIN tblInvoices 
      ON tblCustomers.CustomerID=tblInvoices.CustomerID 
      GROUP BY [Last Name] & ', ' & [First Name] 
PIVOT Format(InvoiceDate, 'yyyy') 
   IN ('1996','1997','1998','1999','2000') 

Observe que a função de agregação é a função SUM, os títulos verticais estão na cláusula GROUP BY da instrução SELECT e os títulos horizontais são determinados pelo campo listado após a palavra-chave PIVOT.

Suporte e comentários

Tem dúvidas ou quer enviar comentários sobre o VBA para Office ou sobre esta documentação? Confira Suporte e comentários sobre o VBA para Office a fim de obter orientação sobre as maneiras pelas quais você pode receber suporte e fornecer comentários.