Las vinculaciones entre tablas se realiza mediante la cl�usula INNER que combina registros de dos tablas siempre que haya concordancia de valores en un campo com�n. Su sintaxis es:
SELECT campos FROM tb1 INNER JOIN tb2 ON tb1.campo1 comp tb2.campo2
En donde:
- tb1, tb2
- Son los nombres de las tablas desde las que se combinan los registros.
- campo1, campo2
- Son los nombres de los campos que se combinan. Si no son num�ricos, los campos deben ser del mismo tipo de datos y contener el mismo tipo de datos, pero no tienen que tener el mismo nombre.
- comp
- Es cualquier operador de comparaci�n relacional : =, <, >, <=, >=, o <>.
Se puede utilizar una operaci�n INNER JOIN en cualquier cl�usula FROM. Esto crea una combinaci�n por equivalencia, conocida tambi�n como uni�n interna. Las combinaciones Equi son las m�s comunes; �stas combinan los registros de dos tablas siempre que haya concordancia de valores en un campo com�n a ambas tablas. Se puede utilizar INNER JOIN con las tablas Departamentos y Empleados para seleccionar todos los empleados de cada departamento. Por el contrario, para seleccionar todos los departamentos (incluso si alguno de ellos no tiene ning�n empleado asignado) se emplea LEFT JOIN o todos los empleados (incluso si alguno no est� asignado a ning�n departamento), en este caso RIGHT JOIN.
Si se intenta combinar campos que contengan datos Memo u Objeto OLE, se produce un error. Se pueden combinar dos campos num�ricos cualesquiera, incluso si son de diferente tipo de datos. Por ejemplo, puede combinar un campo Num�rico para el que la propiedad Size de su objeto Field est� establecida como Entero, y un campo Contador.
El ejemplo siguiente muestra c�mo podr�a combinar las tablas Categor�as y Productos bas�ndose en el campo IDCategoria:
SELECT Nombre_Categor�a, NombreProducto FROM Categorias INNER JOIN Productos ON Categorias.IDCategoria = Productos.IDCategoria;
En el ejemplo anterior, IDCategoria es el campo combinado, pero no est� incluido en la salida de la consulta ya que no est� incluido en la instrucci�n SELECT. Para incluir el campo combinado, incluir el nombre del campo en la instrucci�n SELECT, en este caso, Categorias.IDCategoria.
Tambi�n se pueden enlazar varias cl�usulas ON en una instrucci�n JOIN, utilizando la sintaxis siguiente:
SELECT campos FROM tabla1 INNER JOIN tabla2 ON tb1.campo1 comp tb2.campo1 AND ON tb1.campo2 comp tb2.campo2) OR ON tb1.campo3 comp tb2.campo3)];
Tambi�n puede anidar instrucciones JOIN utilizando la siguiente sintaxis:
SELECT campos FROM tb1 INNER JOIN (tb2 INNER JOIN [( ]tb3 [INNER JOIN [( ]tablax [INNER JOIN ...)] ON tb3.campo3 comp tbx.campox)] ON tb2.campo2 comp tb3.campo3) ON tb1.campo1 comp tb2.campo2;
Un LEFT JOIN o un RIGHT JOIN puede anidarse dentro de un INNER JOIN, pero un INNER JOIN no puede anidarse dentro de un LEFT JOIN o un RIGHT JOIN.
Por ejemplo:
SELECT DISTINCTROW Sum([Precio unidad] * [Cantidad]) AS [Ventas], [Nombre] & " " & [Apellidos] AS [Nombre completo] FROM [Detalles de pedidos], Pedidos, Empleados, Pedidos INNER JOIN [Detalles de pedidos] ON Pedidos. [ID de pedido] = [Detalles de pedidos].[ID de pedido], Empleados INNER JOIN Pedidos ON Empleados.[ID de empleado] = Pedidos.[ID de empleado] GROUP BY [Nombre] & " " & [Apellidos];
Crea dos combinaciones equivalentes: una entre las tablas Detalles de pedidos y Pedidos, y la otra entre las tablas Pedidos y Empleados. Esto es necesario ya que la tabla Empleados no contiene datos de ventas y la tabla Detalles de pedidos no contiene datos de los empleados. La consulta produce una lista de empleados y sus ventas totales.
Si empleamos la cl�usula INNER en la consulta se seleccionar�n s�lo aquellos registros de la tabla de la que hayamos escrito a la izquierda de INNER JOIN que contengan al menos un registro de la tabla que hayamos escrito a la derecha. Para solucionar esto tenemos dos cl�usulas que sustituyen a la palabra clave INNER, estas cl�usulas son LEFT y RIGHT. LEFT toma todos los registros de la tabla de la izquierda aunque no tengan ning�n registro en la tabla de la izquierda. RIGHT realiza la misma operaci�n pero al contrario, toma todos los registros de la tabla de la derecha aunque no tenga ning�n registro en la tabla de la izquierda.
La sintaxis expuesta anteriormente pertenece a ACCESS, en donde todas las sentencias con la sintaxis funcionan correctamente. Los manuales de SQL-SERVER dicen que esta sintaxis es incorrecta y que hay que a�adir la palabra reservada OUTER: LEFT OUTER JOIN y RIGHT OUTER JOIN. En la pr�ctica funciona correctamente de una u otra forma.
No obstante, los INNER JOIN ORACLE no es capaz de interpretarlos, pero existe una sintaxis en formato ANSI para los INNER JOIN que funcionan en todos los sistemas. Tomando como referencia la siguiente sentencia:
SELECT Facturas.*, Albaranes.* FROM Facturas INNER JOIN Albaranes ON Facturas.IdAlbaran = Albaranes.IdAlbaran WHERE Facturas.IdCliente = 325
La transformaci�n de esta sentencia a formato ANSI ser�a la siguiente:
SELECT Facturas.*, Albaranes.* FROM Facturas, Albaranes WHERE Facturas.IdAlbaran = Albaranes.IdAlbaran AND Facturas.IdCliente = 325
Como se puede observar los cambios realizados han sido los siguientes:
- Todas las tablas que intervienen en la consulta se especifican en la cl�usula FROM.
- Las condiciones que vinculan a las tablas se especifican en la cl�usula WHERE y se vinculan mediante el operador l�gico AND.
Referente a los OUTER JOIN, no funcionan en ORACLE y adem�s no conozco una sintaxis que funcione en los tres sistemas. La sintaxis en ORACLE es igual a la sentencia anterior pero a�adiendo los caracteres (+) detr�s del nombre de la tabla en la que deseamos aceptar valores nulos, esto equivale a un LEFT JOIN:
SELECT Facturas.*, Albaranes.* FROM Facturas, Albaranes WHERE Facturas.IdAlbaran = Albaranes.IdAlbaran (+) AND Facturas.IdCliente = 325
Y esto a un RIGHT JOIN:
SELECT Facturas.*, Albaranes.* FROM Facturas, Albaranes WHERE Facturas.IdAlbaran (+) = Albaranes.IdAlbaran AND Facturas.IdCliente = 325
En SQL-SERVER se puede utilizar una sintaxis parecida, en este caso no se utiliza los caracteres (+) sino los caracteres =* para el LEFT JOIN y *= para el RIGHT JOIN.
�Consultas de Autocombinaci�n
La autocombinaci�n se utiliza para unir una tabla consigo misma, comparando valores de dos columnas con el mismo tipo de datos. La sintaxis en la siguiente:
SELECT alias1.columna, alias2.columna, ... FROM tabla1 as alias1, tabla2 as alias2 WHERE alias1.columna = alias2.columna AND otras condiciones
Por ejemplo, para visualizar el n�mero, nombre y puesto de cada empleado, junto con el n�mero, nombre y puesto del supervisor de cada uno de ellos se utilizar�a la siguiente sentencia:
SELECT t.num_emp, t.nombre, t.puesto, t.num_sup,s.nombre, s.puesto FROM empleados AS t, empleados AS s WHERE t.num_sup = s.num_emp
�Consultas de Combinaciones no Comunes
La mayor�a de las combinaciones est�n basadas en la igualdad de valores de las columnas que son el criterio de la combinaci�n. Las no comunes se basan en otros operadores de combinaci�n, tales como NOT, BETWEEN, <>, etc.
Por ejemplo, para listar el grado salarial, nombre, salario y puesto de cada empleado ordenando el resultado por grado y salario habr�a que ejecutar la siguiente sentencia:
SELECT grados.grado,empleados.nombre, empleados.salario, empleados.puesto FROM empleados, grados WHERE empleados.salario BETWEEN grados.salarioinferior AND grados.salariosuperior ORDER BY grados.grado, empleados.salario
Para listar el salario medio dentro de cada grado salarial habr�a que lanzar esta otra sentencia:
SELECT grados.grado, AVG(empleados.salario) FROM empleados, grados WHERE empleados.salario BETWEEN grados.salarioinferior AND grados.salariosuperior GROUP BY grados.grado
�CROSS JOIN (SQL-SERVER)
Se utiliza en SQL-SERVER para realizar consultas de uni�n. Supongamos que tenemos una tabla con todos los autores y otra con todos los libros. Si dese�ramos obtener un listado combinar ambas tablas de tal forma que cada autor apareciera junto a cada t�tulo, utilizar�amos la siguiente sintaxis:
SELECT Autores.Nombre, Libros.Titulo FROM Autores CROSS JOIN Libros
�SELF JOIN
SELF JOIN es una t�cnica empleada para conseguir el producto cartesiano de una tabla consigo misma. Su utilizaci�n no es muy frecuente, pero pongamos alg�n ejemplo de su utilizaci�n.
Supongamos la siguiente tabla (El campo autor es num�rico, aunque para ilustrar el ejemplo utilice el nombre):
C�digo (C�digo del libro) | Autor (Nombre del Autor) |
---|---|
B0012 | 1. Francisco L�pez |
B0012 | 2. Javier Alonso |
B0012 | 3. Marta Rebolledo |
C0014 | 1. Francisco L�pez |
C0014 | 2. Javier Alonso |
D0120 | 2. Javier Alonso |
D0120 | 3. Marta Rebolledo |
Queremos obtener, para cada libro, parejas de autores:
SELECT A.Codigo, A.Autor, B.Autor FROM Autores A, Autores B WHERE A.Codigo = B.Codigo
El resultado es el siguiente:
C�digo | Autor | Autor |
---|---|---|
B0012 | 1. Francisco L�pez | 1. Francisco L�pez |
B0012 | 1. Francisco L�pez | 2. Javier Alonso |
B0012 | 1. Francisco L�pez | 3. Marta Rebolledo |
B0012 | 2. Javier Alonso | 2. Javier Alonso |
B0012 | 2. Javier Alonso | 1. Francisco L�pez |
B0012 | 2. Javier Alonso | 3. Marta Rebolledo |
B0012 | 3. Marta Rebolledo | 3. Marta Rebolledo |
B0012 | 3. Marta Rebolledo | 2. Javier Alonso |
B0012 | 3. Marta Rebolledo | 1. Francisco L�pez |
C0014 | 1. Francisco L�pez | 1. Francisco L�pez |
C0014 | 1. Francisco L�pez | 2. Javier Alonso |
C0014 | 2. Javier Alonso | 2. Javier Alonso |
C0014 | 2. Javier Alonso | 1. Francisco L�pez |
D0120 | 2. Javier Alonso | 2. Javier Alonso |
D0120 | 2. Javier Alonso | 3. Marta Rebolledo |
D0120 | 3. Marta Rebolledo | 3. Marta Rebolledo |
D0120 | 3. Marta Rebolledo | 2. Javier Alonso |
Como podemos observar, las parejas de autores se repiten en cada uno de los libros, podemos omitir estas repeticiones de la siguiente forma
SELECT A.Codigo, A.Autor, B.Autor FROM Autores A, Autores B WHERE A.Codigo = B.Codigo AND A.Autor < B.AutorEl resultado ahora es el siguiente:
C�digo | Autor | Autor |
---|---|---|
B0012 | 1. Francisco L�pez | 2. Javier Alonso |
B0012 | 1. Francisco L�pez | 3. Marta Rebolledo |
C0014 | 1. Francisco L�pez | 2. Javier Alonso |
D0120 | 2. Javier Alonso | 3. Marta Rebolledo |
Ahora tenemos un conjunto de resultados en formato Autor - CoAutor.
Si en la tabla de empleados quisi�ramos extraer todas las posibles parejas que podemos realizar, utilizar�amos la siguiente sentencia:
SELECT Hombres.Nombre, Mujeres.Nombre FROM Empleados Hombre, Empleados Mujeres WHERE Hombre.Sexo = 'Hombre' AND Mujeres.Sexo = 'Mujer' AND Hombres.Id <>Mujeres.Id
Para concluir supongamos la tabla siguiente:
Id | Nombre | SuJefe |
---|---|---|
1 | Marcos | 6 |
2 | Lucas | 1 |
3 | Ana | 2 |
4 | Eva | 1 |
5 | Juan | 6 |
6 | Antonio | � |
Queremos obtener un conjunto de resultados con el nombre del empleado y el nombre de su jefe:
SELECT Emple.Nombre, Jefes.Nombre FROM Empleados Emple, Empleados Jefe WHERE Emple.SuJefe = Jefes.Id