Está en la página 1de 9

TRANSACT-SQL

C ONSULTAS ENLAZA DAS (J OINS )


Muchas veces las consultas que se desean lleva a cabo es de información que se encuentra divida en más de
una tabla. Para realizar este tipo de consulta lo primero es saber el tipo de relación que existe entre cada una
de las tablas y los campos que representan dicha relación. Una condición de tipo “Join” define entonces la
forma en la que dos tablas se relacionan indicando las columnas debidas en cada tabla y el operador apropiado
para realizar la comparación.

Un JOIN se hace básicamente entre un FOREIGN KEY y un PRIMARY KEY. El FOREIGN KEY representa
cualquier campo o unión de campos en la tabla A que necesitan ser validados contra campos similares en la
tabla B en donde dichos campos son PRIMARY KEY.

Sintaxis:
PRIMERA TABLA
Tipo de JOIN
SEGUNDA TABLA
ON ( Condicion del JOIN )

Figure 1. La tabla de facturas está relacionada a la tabla de clientes por el campo IdCliente, el cual es un FK en la tabla de
facturas y un PK en la tabla de clientes.

SELECT Facturas.* ,Cliente.Nombre


FROM facturas
INNER JOIN cliente ON ( Facturas.idCliente = Cliente.IdCliente)

SQL Server – Carlos Caraballo Page 1


TIPOS DE JOIN S
Los tipos de JOINs definen el tipo de evaluación que se ejecuta en la relación, estos pueden ser:

• INNER. Incluye todas las filas de la tabla A donde el operador de comparación (= o <> ) se cumpla en
tabla B. Por ejemplo: sacar todos los empleados y el nombre del departamento al que pertenece, esto
implica que para cada departamento en empleado debe haber registro en la tabla de departamento o
esa fila no sale en la consulta.
• OUTER. Incluye todas las filas de la tabla A aunque no exista un equivalente en la tabla B. Por ejemplo,
si tenemos algunos empleados cuyo departamento no se encuentra definido en la tabla de
departamentos, con el OUTER JOIN aun así el empleado sería mostrado.

El OUTER JOIN puede ser LEFT, RIGHT o FULL de tal modo que se le pueda indicar cuál es la tabla
principal de la cual se van a sacar todos los registros aunque no existan equivalentes en la tabla
secundaria.

• CROSS. Representa el producto cartesiano, todos los registros de la tabla A son combinados con todos
los registros de la tabla B.

INNER JOIN. Saca todos los registros de la tabla A para los que exista una contraparte en la tabla B.

Cada empleado pertenece a un departamento, esa relación se hace posible a través del campo id de departamento.

Departamento:
IdDep Nombre
----------- --------------------------------------------------
1 Operaciones
2 Cobro
5 Legal

Empleado:
IdEmp nombre IdDep
----------- -------------------------------------------------- -----------
1 Carlos 1
2 Pedro 1
3 Maria 2
4 Juan 3

Si queremos mostrar un listado de empleados deberíamos presentar no solo el código del departamento al que
pertenece sino también el nombre dicho departamento.

SQL Server – Carlos Caraballo Page 2


select emp.IdEmp, emp.nombre ,dep.Nombre as [Nombre Departamento]
from Empleado emp
inner join Departamento dep on emp.IdDep = dep.IdDep
Cada empleado pertenece a un departamento, esa relación se hace posible a través del campo id de departamento.

Resultado:
IdEmp nombre Nombre Departamento
----------- -------------------------------------------------- --------------------------------------------------
1 Carlos Operaciones
2 Pedro Operaciones
3 Maria Cobro

select emp.IdEmp, emp.nombre ,dep.Nombre as [Nombre Departamento]


from Empleado emp
inner join Departamento dep on emp.IdDep = dep.IdDep
Where emp.idEmp = 2
Si de la consulta anterior quisiéramos solo el empleado 2 entonces vale aplicar un filtro a toda la consulta.

SELECT codigo, nombre AS Nombre_Empleado FROM empleado WHERE sueldo > 100
La columna nombre en el resultado saldrá con el título Nombre_Empleado. Si en el ALIAS se necesita introducir espacios
entonces se debe utilizar el corchete: [Nombre Empleado].

OUTER JOIN. Muestra todo lo de la tabla A aunque no exista una contra parte en la tabla B. En el OUTER
podemos aplicar las variantes LEFT y RIGHT para indicar cuál es la principal en la relación, también existe la
variante FULL para indicar que puede haber faltas en ambos sentidos.

Con el ejemplo anterior se pudo observar que aplicando el INNER JOIN el empleado 4 no sale, esto se debe a que no
existe un departamento con el código 3. Aplicando el LEFT JOIN logramos que el empleado 4 salga aunque no existe su
contra parte en departamentos.

Select emp.IdEmp, emp.nombre ,dep.Nombre as [Nombre Departamento]


from Empleado emp
left outer join Departamento dep on emp.IdDep = dep.IdDep

Resultado:
IdEmp nombre Nombre Departamento
----------- -------------------------------------------------- --------------------------------------------------
1 Carlos Operaciones
2 Pedro Operaciones
3 Maria Cobro
4 Juan NULL

SQL Server – Carlos Caraballo Page 3


select emp.IdEmp, emp.nombre ,dep.Nombre as [Nombre Departamento]
from Empleado emp
right outer join Departamento dep on emp.IdDep = dep.IdDep
Si cambiamos a RIGTH OUTER entonces sacaremos cada empleado aunque no exista su contraparte en empleados.

Resultado:
IdEmp nombre Nombre Departamento
----------- -------------------------------------------------- --------------------------------------------------
1 Carlos Operaciones
2 Pedro Operaciones
3 Maria Cobro
NULL NULL Legal

Y si finalmente cambiamos a FULL OUTER tendremos al empleado juan sin departamento y al departamento Legal sin
empleado.
Select emp.IdEmp, emp.nombre ,dep.Nombre as [Nombre Departamento]
from Empleado emp
full outer join Departamento dep on emp.IdDep = dep.IdDep

Resultado:
IdEmp nombre Nombre Departamento
----------- -------------------------------------------------- ---------------------------------
1 Carlos Operaciones
2 Pedro Operaciones
3 Maria Cobro
NULL NULL Legal
4 Juan NULL

SQL Server – Carlos Caraballo Page 4


UPDATES
Cuando los registros que se van a actualizar necesitan una condición de búsqueda especial donde participan
otras tablas es necesario realizar un JOIN o sub-consulta.

UPDATE facturas SET montocredito = 0


FROM facturas
INNER JOIN cliente ON facturas.idcliente = cliente.idcliente
WHERE cliente.estado = 1

Esta actualización afecta todas las facturas donde el cliente se encuentre en estado = 1. La condición del
estado se encuentra dentro de otra tabla, por eso es necesario establecer una relación.

SQL Server – Carlos Caraballo Page 5


E XPRESIONE S DE TABLAS COMUNES (CTE)
Las CTEs es una característica agregada a partir del SQL 2005 la cual permite crear una especie de tabla
temporal en el ámbito de alguna sentencia como SELECT, INSERT, DELETE, UPDATE o CREATE VIEW. Es como
crear una vista por un corto tiempo para ser utilizada por alguna otra sentencia.

Una de las características principales de las CTE es la posibilidad de permitir consultas recursivas. Es decir,
consultas donde es necesario referirse a la misma tabla n veces.

WITH Tpagos ( idEmp, total )


(
SELECT idEmp, SUM(monto)
FROM pagos
GROUP BY idemp
)
SELECT empleados.*, tpagos.total
FROM empleados INNER JOIN Tpagos ON empleados.idEmp = tpagos.idEmp
GO
Esta consulta de empleados saca el total pagado a cada empleado, pero dicho total sale de una tabla temporal creada al
inicio de la sentencia.

SQL Server – Carlos Caraballo Page 6


C O N SU L TA S R E C U R SI V A S
En estas consultas es necesario referirse n veces a la misma tabla durante la consulta de manera jerárquica.
Para esto es necesario incluir una cláusula UNION dentro CTE. Para evitar un bucle infinito puede ser necesario
incluir la opción MAXRECURTION.

Para ilustrar el caso vamos a tomar el ejemplo del señor Robert Sheldon, el cual se encuentra en unos de los
enlaces de referencias, en ese ejemplo se tiene una tabla de empleados donde se dice que cada empleado
tiene un Manager, y este Manager a su vez es un empleado. Esto quiere decir que para mostrar el empleado
con sus datos y los datos manager se necesita ir a la misma tabla de empleado por cada registro, esto es
recursivo.

GO

CREATE TABLE dbo.Employees


(
EmployeeID int NOT NULL PRIMARY KEY,
FirstName varchar(50) NOT NULL,
LastName varchar(50) NOT NULL,
ManagerID int NULL
)

GO

INSERT INTO Employees VALUES (101, 'Ken', 'Sánchez', NULL)


INSERT INTO Employees VALUES (102, 'Terri', 'Duffy', 101)
INSERT INTO Employees VALUES (103, 'Roberto', 'Tamburello', 101)
INSERT INTO Employees VALUES (104, 'Rob', 'Walters', 102)
INSERT INTO Employees VALUES (105, 'Gail', 'Erickson', 102)
INSERT INTO Employees VALUES (106, 'Jossef', 'Goldberg', 103)
INSERT INTO Employees VALUES (107, 'Dylan', 'Miller', 103)
INSERT INTO Employees VALUES (108, 'Diane', 'Margheim', 105)
INSERT INTO Employees VALUES (109, 'Gigi', 'Matthew', 105)
INSERT INTO Employees VALUES (110, 'Michael', 'Raheem', 106)

SQL Server – Carlos Caraballo Page 7


WITH
cteReports (EmpID, FirstName, LastName, MgrID, EmpLevel)
AS
(
SELECT EmployeeID, FirstName, LastName, ManagerID, 1
FROM Employees
WHERE ManagerID IS NULL
UNION ALL
SELECT e.EmployeeID, e.FirstName, e.LastName, e.ManagerID,
r.EmpLevel + 1
FROM Employees e
INNER JOIN cteReports r
ON e.ManagerID = r.EmpID
)

SELECT
FirstName + ' ' + LastName AS FullName,
EmpLevel,
(SELECT FirstName + ' ' + LastName FROM Employees
WHERE EmployeeID = cteReports.MgrID) AS Manager
FROM cteReports
ORDER BY EmpLevel, MgrID

SQL Server – Carlos Caraballo Page 8


R EFERENCIAS
http://msdn.microsoft.com/es-es/library/ms189773.aspx
http://julycastiblanco.blogspot.com/2010/03/expresiones-de-tablas-comunes-cte-en.html
http://www.simple-talk.com/sql/t-sql-programming/sql-server-cte-basics/

SQL Server – Carlos Caraballo Page 9