4D v14

Soporte de joins

Inicio

 
4D v14
Soporte de joins

Soporte de joins  


 

 

El motor SQL de 4D amplía el soporte de las sentencias join.

Las sentencias join puede ser internas o externas, implícitas o explícitas. Las joins internas (INNER joins) implicitas son soportadas por el comando SELECT. También puede generar joins internas y externas explícitas utilizando la palabra clave SQL JOIN.

Nota: la implementación actual de joins en el motor SQL de 4D no incluye:

  • joins naturales.
  • el constructor USING en las joins internas.

Las sentencias join permiten hacer conexiones entre los registros de dos o más tablas y combinar el resultado en una tabla nueva, llamada join.

Genere joins vía las instrucciones SELECT que especifican las condiciones de join. Con las joins explícitas, estas condiciones pueden ser complejas, pero siempre deben basarse en una comparación de igualdad entre las columnas incluidas en la join. Por ejemplo, no es posible utilizar el operador >= en una condición de join explícita. Todo tipo de comparación se puede utilizar en una join implícita.
Internamente, las comparaciones de igualdad son efectuadas directamente por el motor de 4D, que garantiza una rápida ejecución.

Nota: Por lo general, en el motor de base de datos, el orden de las tablas está determinado por el orden definido durante la búsqueda. Sin embargo, al usar combinaciones, el orden de las tablas se determina por la lista de tablas. En el ejemplo siguiente:
SELECT * FROM T1 RIGHT OUTER JOIN T2 ON = T2.depID T1.depID;
... el orden de las tablas es T1 y luego T2 (tal como aparecen en la lista de tablas) y no T1 y luego T2 (tal como aparecen en la condición de join).

Una join interna (inner join) está basada en una comparación de igualdad entre dos columnas. Por ejemplo, si consideramos las tres tablas siguientes:

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

  • Cities
    cityIDcityName
    30Paris
    33New York
    NULLBerlin

Nota: esta estructura de ejemplo se utilizará durantes este capítulo. 

Este es un ejemplo de join interna explícita:

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

En 4D, puede también utilizar la palabra clave JOIN para especificar una join interna explícita:

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

Esta búsqueda puede insertarse en el código 4D de la siguiente manera:

 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 el resultado de esta join:

aNameaEmpDepIDaDepIDaDepName
Alan1010Program
Anne1111Engineering
Bernard1010Program
Mark1212Development
Thomas1010Program

Note que ni los empleados Philip o Martin ni los departamentos Marketing o Quality aparecen en la join resultante porque:

  • Philip no tiene un departamento asociado con su nombre (valor NULL),
  • El ID de departamento de Martin no existe en la tabla Departamentos,
  • No hay empleado asociado al departamento de ID 13,
  • El departamento de Marketing no tiene un ID asociado (valor NULL).

Una join interna en la cual la cláusula WHERE y la cláusula ON se omiten se llama join cruzada o cartesiana. Efectuar una join cruzada consiste en asociar cada línea de una tabla a cada línea de otra tabla.
El resultado de una join cruzada es el producto cartesiano de las tablas, con a x b líneas, donde a es el número de líneas de la primera tabla y b es el número de líneas de la segunda tabla. Este producto representa todas las combinaciones posibles formadas por la concatenación de líneas de ambas tablas. 

Cada una de las siguientes sintaxis son equivalentes:

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

Este es un ejemplo de código 4D integrando una 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 de esta join con nuestra base de ejemplo:

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 razones de rendimiento, las joins cruzadas deben utilizarse con cuidado.

Ahora puede generar joins externas con 4D (OUTER JOINs). En una join externa, no es necesario que haya una correspondencia entre las líneas de las tablas combinadas. La tabla resultante contiene todas las líneas de las tablas (o de al menos una de las tablas combinadas), incluso si no hay líneas correspondientes. Esto significa que toda la información de una tabla puede ser utilizada, aunque las líneas no se llenan por completo entre las diferentes tablas unidas.

Hay tres tipos de joins externas, definidas por las palabras claves LEFT, RIGHT y FULL. LEFT y RIGHT se utilizan para indicar la tabla (ubicada a la izquierda o a la derecha de la palabra clave JOIN) en la que todos los datos deben ser procesados. FULL indica una join externa bilateral.

Nota: sólo las joins externas explícitas son soportadas por 4D.

El resultado de una join externa izquierda (o left join) siempre contiene todos los registros de la tabla situada a la izquierda de la palabra clave, incluso si la condición de join no encuentra un registro correspodiente en la tabla a la derecha. Esto significa que para cada línea de la tabla de la izquierda, donde la búsqueda no encuentra ninguna línea correpondiente en la tabla de la derecha, la join contendrá la línea con valores NULL para cada columna de la tabla de la derecha. En otras palabras, una join externa izquierda devuelve todas las líneas de la tabla de la izquierda, además de las de la tabla de la derecha que correspondan a la condición de join (o NULL si ninguna corresponde). Tenga en cuenta que si la tabla de la derecha contiene más de una línea que corresponde con el predicado de la join para una línea de la tabla de la izquierda, los valores de la tabla izquierda se repetirán para cada línea distinta de la tabla derecha.

Este es un ejemplo de código 4D con una join externa izquierda:

 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 es el resultado de esta join con nuestra base de ejemplo (las líneas adicionales se muestran en rojo):

aNameaEmpDepIDaDepIDaDepName
Alan1010Program
Anne1111Engineering
Bernard1010Program
Mark1212Development
Thomas1010Program
Martin15NULLNULL
PhilipNULLNULLNULL

Una join externa derecha es el opuesto exacto de una join externa izquierda. Su resultado siempre contiene todos los registros de la tabla ubicada a la derecha de la palabra clave JOIN incluso si la condición join no encuentra un registro correspondiente en la tabla izquierda. 

Este es un ejemplo de código 4D con una join externa derecha:

 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 es el resultado de esta join con nuestra base de ejemplo (las líneas adicionales están en rojo):

aNameaEmpDepIDaDepIDaDepName
Alan1010Program
Anne1111Engineering
Bernard1010Program
Mark1212Development
Thomas1010Program
NULLNULLNULLMarketing
NULLNULL13Quality

Una join externa bilateral combina los resultados de una join externa izquierda y de una join externa derecha. La tabla join resultante contiene todos los registros de las tablas izquierda y derecha y llena los campos faltantes de cada lado valores NULL. 

Este es un ejemplo de código 4D con una 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 es el resultado de esta join con nuestra base de ejemplo (las líneas adicionales se muestran en rojo):

aNameaEmpDepIDaDepIDaDepName
Alan1010Program
Anne1111Engineering
Bernard1010Program
Mark1212Development
Thomas1010Program
Martin15NULLNULL
PhilipNULLNULLNULL
NULLNULLNULLMarketing
NULLNULL13Quality

Es posible combinar varias joins en la misma instrucción SELECT. También es posible combinar joins internas implícitas o explicitas y joins externas explícitas.

Este es un ejemplo de código 4D con joins múltiples:

 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 es el resultado de esta join con nuestra base de ejemplo:

aNameaEmpDepIDaEmpCityIDaDepIDaDepNameaCityIDaCityName
Alan103010Program30Paris
Anne113911Engineering0    
Bernard103310Program33New York
Mark123512Development 0
Thomas10NULL10Program0   

 
PROPIEDADES 

Producto: 4D
Tema: Utilizar SQL en 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)