4D v14

Suporte de joins

Página Inicial

 
4D v14
Suporte de joins

Suporte de joins  


 

 

O motor SQL de 4D amplia o suporte das sentenças join.

As sentenças join podem ser internas ou externas, implícitas ou explícitas. As joins internas (INNER joins) implícitas são suportadas pelo comando SELECT. Também pode gerar joins internas e externas explícitas utilizando a palavra chave SQL JOIN.

Nota: A implementação atual de joins no motor SQL de 4D não inclui:

  • joins naturais.
  • o construtor USING nas joins internas.

As sentenças join permitem fazer conexões entre os registros de duas ou mais tabelas e combinar o resultado em uma tabela nova, chamada join.

Gere joins via as instruções SELECT que especificam as condições de join. Com as joins explícitas, estas condições podem ser complexas, mas sempre devem ser baseadas em uma comparação de igualdade entre as colunas incluídas na join. Por exemplo, não é possível utilizar o operador >= em uma condição de join explícita. Todo tipo de comparação pode ser utilizada em uma join implícita.
Internamente, as comparações de igualdade são realizadas diretamente pelo motor de 4D, que garante uma rápida execução.

Nota: Geralmente, no motor do banco de dados, a ordem das tabelas está determinada pela ordem definida durante a pesquisa. No entanto, ao usar combinações, a ordem das tabelas são determinadas pela lista de tabelas. No seguinte exemplo:
SELECT * FROM T1 RIGHT OUTER JOIN T2 ON = T2.depID T1.depID;
... a ordem das tabelas é T1 e depois T2 (tal como aparecem na lista de tabelas) e não T1 e depois T2 (tal como aparecem na condição de join).

Uma join interna (inner join) está baseada em uma comparação de igualdade entre duas colunas. Por exemplo, se consideramos as seguintes três tabelas:

  • Employees
    namedepIDcityID
    Alan1030
    Anne1139
    Bernard1033
    Mark1235
    Martin1530
    PhilipNULL33
    Thomas10NULL
  • Departments
    depIDdepName
    10Program
    11Engineering
    NULLMarketing
    12Development
    13Quality

  • Cities
    cityIDcityName
    30Paris
    33New York
    NULLBerlin

Nota: Esta estrutura de exemplo será utilizada durante este capítulo. 

Este é um exemplo de join interna explícita:

SELECT *  
        FROM employees, departments
        WHERE employees.DepID = departments.DepID;

Em 4D, pode também utilizar a palavra chave JOIN para especificar uma join interna explícita:

SELECT *
        FROM employees
        INNER JOIN departments
            ON employees.DepID = departments.DepID;

Esta pesquisa pode ser inserida no código 4D da seguinte forma:

 ARRAY TEXT(aName;0)
 ARRAY TEXT(aDepName;0)
 ARRAY INTEGER(aEmpDepID;0
 ARRAY INTEGER(aDepID;0)
 Begin SQL
        SELECT *
        FROM employees
                INNER JOIN departments
                    ON employees.depID = departments.depID
                INTO :aName, :aEmpDepID, :aDepID, :aDepName;
 End SQL

Este é o resultado desta join:

aNameaEmpDepIDaDepIDaDepName
Alan1010Program
Anne1111Engineering
Bernard1010Program
Mark1212Development
Thomas1010Program

Note que nem os empregados Philip ou Martin nem os departamentos Marketing ou Quality aparecem na join resultante porque:

  • Philip não tem um departamento associado com seu nome (valor NULL),
  • O ID de departamento de Martin não existe na tabela Departamentos,
  • Não há empregado associado ao departamento de ID 13,
  • O departamento de Marketing não tem um ID associado (valor NULL).

Uma join interna na qual a cláusula WHERE e a cláusula ON são omitidas, se chamam join cruzada ou cartesiana. Realizar uma join cruzada consiste em associar cada linha de uma tabela a cada linha de outra tabela.
O resultado de uma join cruzada é o produto cartesiano das tabelas, com a x b linhas, onde a é o número de linhas da primeira tabela e b é o número de linhas da segunda tabela. Este produto representa todas as combinações possíveis formadas pela concatenação de linhas de ambas tabelas. 

Cada uma das seguintes sintaxes são equivalentes:

    SELECT * FROM T1 INNER JOIN T2
    SELECT * FROM T1, T2
    SELECT * FROM T1 CROSS JOIN T2;

Este é um exemplo de código 4D integrando uma join cruzada:

 ARRAY TEXT(aName;0)
 ARRAY TEXT(aDepName;0)
 ARRAY INTEGER(aEmpDepID;0
 ARRAY INTEGER(aDepID;0)
 Begin SQL
        SELECT *
        FROM employees CROSS JOIN departments
                INTO :aName, :aEmpDepID, :aDepID, :aDepName;
 End SQL

Resultado desta join com nossa base de exemplo:

aNameaEmpDepIDaDepIDaDepName
Alan1010Program
Anne1110Program
Bernard1010Program
Mark1210Program
Martin1510Program
PhilipNULL10Program
Thomas1010Program
Alan1011Engineering
Anne1111Engineering
Bernard1011Engineering
Mark1211Engineering
Martin1511Engineering
PhilipNULL11Engineering
Thomas1011Engineering
Alan10NULLMarketing
Anne11NULLMarketing
Bernard10NULLMarketing
Mark12NULLMarketing
Martin15NULLMarketing
PhilipNULLNULLMarketing
Thomas10NULLMarketing
Alan1012Development
Anne1112Development
Bernard1012Development
Mark1212Development
Martin1512Development
PhilippeNULL12Development
Thomas1012Development
Alain1013Quality
Anne1113Quality
Bernard1013Quality
Mark1213Quality
Martin1513Quality
PhilipNULL13Quality
Thomas1013Quality

Nota: Por razões de rendimento, as joins cruzadas devem ser utilizadas com cuidado.

Agora pode gerar joins externas com 4D (OUTER JOINs). Em uma join externa, não é necessário que tenha uma correspondência entre as linhas das tabelas combinadas. A tabela resultante contém todas as linhas das tabelas (ou de pelo menos uma das tabelas combinadas), inclusive se não há linhas correspondentes. Isto significa que toda a informação de uma tabela pode ser utilizada, ainda que as linhas não enchem completamente entre as diferentes tabelas unidas.

Há três tipos de joins externas, definidas pelas palavras chaves LEFT, RIGHT e FULL. LEFT e RIGHT se utilizam para indicar a tabela (localizada a esquerda ou a direita da palavra chave JOIN) na que todos os dados devem ser processados. FULL indica uma join externa bilateral.

Nota: Somente as joins externas explícitas são suportadas por 4D.

O resultado de uma join externa esquerda (ou left join) sempre contém todos os registros da tabela situada a esquerda da palavra chave, inclusive se a condição de join não encontra um registro correspondente na tabela a direita. Isto significa que para cada linha da tabela da esquerda, onde a pesquisa não encontra nenhuma linha correspondente na tabela da direita, a join vai conter a linha com valores NULL para cada coluna da tabela da direita. Em outras palavras, uma join externa esquerda devolve todas as linhas da tabela da esquerda, além das da tabela da direita que correspondam a condição de join (ou NULL se nenhuma corresponde). Tenha em conta que se a tabela da direita contém mais de uma linha que corresponde com o predicado da join para uma linha da tabela da esquerda, os valores da tabela esquerda serão repetidas para cada linha diferente da tabela direita.

Este é um exemplo de código 4D com uma join externa esquerda:

 ARRAY TEXT(aName;0)
 ARRAY TEXT(aDepName;0)
 ARRAY INTEGER(aEmpDepID;0
 ARRAY INTEGER(aDepID;0)
 Begin SQL
        SELECT *
            FROM employees
            LEFT OUTER JOIN departments
                ON employees.DepID = departments.DepID;
                INTO :aName, :aEmpDepID, :aDepID, :aDepName;
 End SQL

Este é o resultado desta join com nossa base de exemplo (as linhas adicionais são mostradas em vermelho):

aNameaEmpDepIDaDepIDaDepName
Alan1010Program
Anne1111Engineering
Bernard1010Program
Mark1212Development
Thomas1010Program
Martin15NULLNULL
PhilipNULLNULLNULL

Uma join externa direita é o oposto exato de uma join externa esquerda. Seu resultado sempre contém todos os registros da tabela localizada a direita da palavra chave JOIN inclusive se a condição join não encontra um registro correspondente na tabela esquerda. 

Este é um exemplo de código 4D com uma join externa direita:

 ARRAY TEXT(aName;0)
 ARRAY TEXT(aDepName;0)
 ARRAY INTEGER(aEmpDepID;0
 ARRAY INTEGER(aDepID;0)
 Begin SQL
        SELECT *
            FROM employees
            RIGHT OUTER JOIN departments
                ON employees.DepID = departments.DepID;
                INTO :aName, :aEmpDepID, :aDepID, :aDepName;
 End SQL

Este é o resultado desta join com nossa base de exemplo (as linhas adicionais estão em vermelho):

aNameaEmpDepIDaDepIDaDepName
Alan1010Program
Anne1111Engineering
Bernard1010Program
Mark1212Development
Thomas1010Program
NULLNULLNULLMarketing
NULLNULL13Quality

Uma join externa bilateral combina os resultados de uma join externa esquerda e de uma join externa direita. A tabela join resultante contém todos os registros das tabelas esquerda e direita e enche os campos que faltam de cada lado valores NULL. 

Este é um exemplo de código 4D com uma join externa bilateral:

 ARRAY TEXT(aName;0)
 ARRAY TEXT(aDepName;0)
 ARRAY INTEGER(aEmpDepID;0
 ARRAY INTEGER(aDepID;0)
 Begin SQL
        SELECT *
            FROM employees
            FULL OUTER JOIN departments
                ON employees.DepID = departments.DepID;
                INTO :aName, :aEmpDepID, :aDepID, :aDepName;
 End SQL

Este é o resultado desta join com nossa base de exemplo (as linhas adicionais são mostradas em vermelho):

aNameaEmpDepIDaDepIDaDepName
Alan1010Program
Anne1111Engineering
Bernard1010Program
Mark1212Development
Thomas1010Program
Martin15NULLNULL
PhilipNULLNULLNULL
NULLNULLNULLMarketing
NULLNULL13Quality

É possível combinar várias joins na mesma instrução SELECT. Também é possível combinar joins internas implícitas ou explicitas e joins externas explícitas.

Este é um exemplo de código 4D com joins múltiplas:

 ARRAY TEXT(aName;0)
 ARRAY TEXT(aDepName;0)
 ARRAY TEXT(aCityName;0)
 ARRAY INTEGER(aEmpDepID;0
 ARRAY INTEGER(aEmpCityID;0)
 ARRAY INTEGER(aDepID;0)
 ARRAY INTEGER(aCityID;0)
 Begin SQL
        SELECT *
            FROM (employees RIGHT OUTER JOIN departments
                        ON employees.depID = departments.depID)
                        LEFT OUTER JOIN cities
                        ON employees.cityID = cities.cityID
            INTO :aName, :aEmpDepID, :aEmpCityID, :aDepID, :aDepName, :aCityID, :aCityName;
 End SQL

Este é o resultado desta join com nossa base de exemplo:

aNameaEmpDepIDaEmpCityIDaDepIDaDepNameaCityIDaCityName
Alan103010Program30Paris
Anne113911Engineering0    
Bernard103310Program33New York
Mark123512Development 0
Thomas10NULL10Program0   

 
PROPRIEDADES 

Produto: 4D
Tema: Utilizar SQL em 4D

 
ARTICLE USAGE

Manual de SQL ( 4D v14)
Manual de SQL ( 4D v12.1)
Manual de SQL ( 4D v13.4)
Manual de SQL ( 4D v14 R2)
Manual de SQL ( 4D v14 R3)
Manual de SQL ( 4D v14 R4)