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: =, <,<>, <=, =>, ó >. |
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
NombreCategoria, 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.
Ejemplo:
SELECT DISTINCT
Sum(PrecioUnitario * Cantidad) AS Sales,
(Nombre + ' ' + Apellido) AS Name
FROM
Empleados
INNER JOIN(
Pedidos
INNER JOIN
DetallesPedidos
ON
Pedidos.IdPedido = DetallesPedidos.IdPedido)
ON
Empleados.IdEmpleado = Pedidos.IdEmpleado
GROUP BY
Nombre + ' ' + Apellido
(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
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:
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.
SELECT
alias1.columna, alias2.columna, ...
FROM
tabla1 as alias1, tabla2 as alias2
WHERE
alias1.columna = alias2.columna
AND
otras condiciones
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
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
SELECT
Autores.Nombre, Libros.Titulo
FROM
Autores CROSS JOIN Libros
| Autores | |
| 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 |
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 |
SELECT
A.Codigo, A.Autor, B.Autor
FROM
Autores A, Autores B
WHERE
A.Codigo = B.Codigo AND A.Autor < B.Autor
El 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 |
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:
| Empleados | ||
| Id | Nombre | SuJefe |
| 1 | Marcos | 6 |
| 2 | Lucas | 1 |
| 3 | Ana | 2 |
| 4 | Eva | 1 |
| 5 | Juan | 6 |
| 6 | Antonio | |
SELECT
Emple.Nombre, Jefes.Nombre
FROM
Empleados Emple, Empleados Jefe
WHERE
Emple.SuJefe = Jefes.Id
| Por: Vlad | 18/2/2006
|
| Por: ixtarix | 05/2/2007
|
| Por: JAhlli | 11/9/2007
|
![]() MarioBu... | Buen articulo | 11/1/2010 |