Académique Documents
Professionnel Documents
Culture Documents
Autor: DesarrollandoSoftware.com Tutorial HTML En bases de datos normalizadas la informacin requerida para una consulta puede localizarse en dos o ms tablas dentro de la base de datos, ahora veremos cmo escribir consultas que usen los operadores INNER, OUTER, FULL y CROSS JOIN, tambin explicaremos la diferencia entre los diferentes operadores JOIN o de combinacin. Para esto continuaremos utilizando el Editor de consultas del Microsoft Management Studio, y las bases de datos Northwind y AdventureWorks.
Combinando tablas relacionadas El operador INNER JOIN El operador OUTER JOIN El operador SELF JOIN
Ahora para la consulta en la clausula SELECT agregamos las columnas que necesitamos, las tablas junto al operador INNER JOIN que es el tipo de unin y finalmente la condicin
USE Northwind; SELECT ProductName,QuantityPerUnit, UnitPrice ,CategoryName, Description FROM dbo.Categories INNER JOIN dbo.Products ON dbo.Categories.CategoryID = dbo.Products.CategoryID;
Veamos otro ejemplo con la base de datos de AdventureWorks El siguiente ejemplo retorna los nombres y apellidos de los empleados de la tabla Person.Contact y el titulo laboral, horas enfermo y horas de vacaciones de la tabla HumanResources.Employee
USE AdventureWorks; SELECT FirstName, LastName, HumanResources.Employee.Title ,SickLeaveHours, VacationHours FROM HumanResources.Employee INNER JOIN Person.Contact ON HumanResources.Employee.ContactID = Person.Contact.ContactID;
En la consulta anterior tuvimos que especificar que la columna title que necesitamos est en la tabla Employee(HumanResources.Employee.Title) esto porque existe el mismo nombre de columna en la tabla Contact.
Como una consulta interna (INNER JOIN) fue definida, las columnas de la tabla HumanResources.Employee que no coinciden con las columnas en Person.Contact no fueron retornadas, si queremos que suceda lo contrario debemos definir una unin externa o OUTER JOIN Outer Joins (Combinaciones externas) Cuando realizamos una combinacin interna los resultados son aquellos que coinciden en ambos campos de la condicin, eliminado aquellas que no coincidan en ambas filas o campos, en el ejemplo anterior en la tabla Person.Contact existen casi 20.000 filas o registros pero necesitbamos filtrar solo a los contactos que sean empleados, 290 registros en total. Una combinacin externa (Outer Join) devuelve una o todas las filas de una de las tablas mencionadas en la clusula FROM, junto a esta clausula debemos utilizar, siempre, ciertos operadores para definir las filas devolver la consulta, los operadores son LEFT, con este se recuperarn las filas de la tabla izquierda a la que se haya hecho referencia, con RIGHT las filas de la tabla derecha a la que se haya hecho referencia sern devueltos y con el operador FULL, se devuelven todas las filas. Veamos el anterior ejemplo con una modificacin utilizando una combinacin externa
USE AdventureWorks; SELECT FirstName, LastName, HumanResources.Employee.Title ,SickLeaveHours, VacationHours FROM HumanResources.Employee RIGHT OUTER JOIN Person.Contact ON HumanResources.Employee.ContactID = Person.Contact.ContactID ORDER BY FirstName;
El resultado de esta consulta ser todos los contactos (tabla a la derecha) y para los que sean empleados obtendremos su titulo laboral, horas enfermo y horas de vacaciones, si cambiamos por ejemplo el operador RIGHT por LEFT obtendremos solo los nombres de los empleados, intntalo. Como se vio en el ejemplo la sintaxis de una combinacin externa es operador OUTER JOIN pero tambin podemos escribir sin la palabra OUTER, solo LEFT JOIN, por ejemplo. Trabajando con ms de dos tablas Podemos unir ms de dos tablas para acceder las columnas requeridas para alguna consulta. Una recomendacin general de rendimiento es limitar en lo posible el nmero de tablas que participan en el JOIN porque SQL Server se tomara ms tiempo en resolver la consulta. El tipo ms comn de JOIN para ms de dos tablas es el INNER JOIN, el siguiente cdigo devuelve el nombre de producto (tabla Products), el precio por producto (tabla Products), el nombre a la categora que pertenece (tabla Categories), una descripcin de esta categora (tabla Categories), la compaa proveedora (tabla Suppliers) y la ciudad del proveedor (tabla Suppliers), de la base de datos Northwind. Como vemos en el diagrama, las tablas estn relacionadas de la siguiente forma: Products.CategoryID (FK) con Categories.CategoryID (PK) Products.SupplierID (FK) con Suppliers.SupplierID (PK)
USE Northwind; SELECT ProductName AS [Nombre del Producto] ,UnitPrice AS [Precio del producto] ,CategoryName AS [Categoria] ,"Description" AS [Descripcion de categoria] ,CompanyName AS [Proveedor] ,City AS [Ciudad del proveedor] FROM dbo.Products P INNER JOIN dbo.Categories C ON P.CategoryID = C.CategoryID
Noten que cuando no utilizamos la palabra reservada AS tomar la siguiente palabra o cadena entre corchetes como el alias, tambin observen que en Description agregamos una comillas esto para evitar el error de Nombre de columna no vlido, producido cuando el SQL no lo reconoce como campo. Ahora veamos un ejemplo con la base de datos AdventureWorks, Ahora necesitamos retornar los nombres y apellidos de los empleados de la tabla Person.Contact, el titulo laboral, horas enfermo y horas de vacaciones de la tabla HumanResources.Employee y la direccin de los empleados de la tabla Person.Address, veamos el diagrama de relaciones:
Al ver el diagrama de tablas vemos que la direccin que necesitamos se encuentra en la tabla Person.Address la que no esta relacionada directamente con la tabla HumanResources.Employee, pero la tabla HumanResources.EmployeeAddress relaciona ambas, veamos como generar la consulta:
USE AdventureWorks; SELECT FirstName, LastName ,HumanResources.Employee.Title, SickLeaveHours, VacationHours ,AddressLine1 FROM HumanResources.Employee INNER JOIN Person.Contact ON HumanResources.Employee.ContactID = Person.Contact.ContactID INNER JOIN HumanResources.EmployeeAddress ON HumanResources.Employee.EmployeeID = HumanResources.EmployeeAddress.EmployeeID INNER JOIN Person."Address" ON HumanResources.EmployeeAddress.AddressID = Person."Address".AddressID;
El resultado contendrn las filas deseadas utilizando tres combinaciones internas, tambin agregamos comentarios que como seguro ya lo notaron tiene la forma -- Comentario Utilizando un Self-Join Una self-join o auto-combinacin es cuando se realiza una consulta a la tabla es referenciada, esto se consigue utilizando un alias diferente cada vez que referenciamos la tabla. Veamos por ejemplo la tabla Employee,en la base de datos AdventureWorks, en esta tabla existe una columna llamada ManagerID, con esta columna podemos saber quien es el superior de cada empleado, ahora lo que queremos es saber quien es el Supervisor de cada empleado, para esto utilizaremos una auto-combinacin, veamos:
USE AdventureWorks SELECT E.EmployeeID, E.Title, M.ManagerID FROM HumanResources.Employee E INNER JOIN HumanResources.Employee M
Ahora para que nuestra consulta sea ms completa la combinaremos con la tabla Contact para obtener el nombre del empleado y el nombre del supervisor
USE AdventureWorks SELECT P.FirstName + ' ' + P.LastName AS 'Nombre del Empleado' , E.Title AS 'Cargo del empleado' , MP.FirstName + ' ' + MP.LastName AS 'Nombre de Supervisor' , M.Title AS 'Cargo del Supervisor' FROM HumanResources.Employee E INNER JOIN HumanResources.Employee M ON E.ManagerID = M.EmployeeID INNER JOIN Person.Contact P
ON E.ContactID = P.ContactID INNER JOIN Person.Contact MP ON M.ContactID = MP.ContactID ORDER BY [Cargo del Supervisor];
Alguien se preguntara porque solo tenemos 289 filas como resultado si es que tenemos 290 empleados, el empleado que falta es el Director ejecutivo (Chief executive officer) que como imaginaran no tiene supervisor por tanto en la columna ManagerID tiene como dato NULL y en la condicin no especificamos que podra existir un valor NULL, para solucionar esto podramos agregar a la condicin del primer JOIN el operador lgico AND quedando:
Para terminar esta entrega del curso hagamos unos ejercicios: EJERCICIOS 1. Escriba y ejecute un cdigo para retornar informacin de la tabla Productos donde el nombre de producto coincida con Queso, use la base de datos Northwind
USE Northwind; SELECT ProductID, CategoryID, ProductName AS [Nombre de Producto] FROM dbo.Products WHERE ProductName LIKE '%Queso%';
Note que en el resultado est incluido el ID de categora pero no el nombre de la categora, ahora en la consulta siguiente escriba y ejecute un cdigo para unir la tabla Productos con la tabla Categoras para recuperar la informacin del nombre de la categora al que pertenece el producto. Puede utilizar una consulta INNER JOIN porque est buscando solo las filas que sean iguales en ambas tablas.
USE Northwind; SElECT ProductID, dbo.Categories.CategoryID, ProductName AS [Nombre de Producto] , CategoryName [Categoria del Producto] FROM dbo.Products INNER JOIN dbo.Categories
Ntese que en la clusula SELECT al momento de indicar la columna CategoryID tuvimos que agregar la tabla a la que pertenece dbo.Categories.CategoryID, esto lo hacemos porque caso contrario SQL no sabr de cul de las tablas tomar la informacin si de Productos o de Categoras y lo interpretara como una ambiguedad. 2. De la base de datos AdventureWorks ejecute un comando que retorne informacin de la tabla ProductSubcategory donde los nombres de subcategorias contengan la palabra bike
USE AdventureWorks; SELECT ProductSubcategoryID, ProductCategoryID ,Name AS 'Nombre de Subcategoria' FROM Production.ProductSubcategory WHERE Name LIKE '%Bike%' ORDER BY [Nombre de Subcategoria];
En la consulta anterior logramos obtener ProductCategoryID pero no el nombre de la Categora, ahora ejecutemos una consulta para combinar la tabla ProductCategory con la tabla ProductSubcategory, para obtener el nombre de categora.
USE AdventureWorks; SELECT ProductSubcategoryID, Production.ProductCategory.ProductCategoryID ,Production.ProductSubcategory.Name AS 'Nombre de Subcategoria' ,Production.ProductCategory.Name AS 'Nombre de Categoria' FROM Production.ProductSubcategory INNER JOIN Production.ProductCategory ON Production.ProductCategory.ProductCategoryID = Production.ProductSubcategory.ProductCategoryID WHERE Production.ProductSubcategory.Name LIKE '%Bike%' ORDER BY [Nombre de Categoria];
Ahora aade la tabla Products para ver que productos existen en cada una de esas subcategorias
USE AdventureWorks; SELECT P.ProductID AS 'ID de Producto' ,PSC.ProductSubcategoryID AS 'ID de Subcategoria' ,PC.ProductCategoryID AS 'ID de Categoria' ,P.Name AS 'Nombre de Producto' ,PSC.Name AS 'Nombre de Subcategoria' ,PC.Name AS 'Nombre de Categoria' FROM Production.ProductSubcategory AS PSC INNER JOIN Production.ProductCategory AS PC ON PC.ProductCategoryID = PSC.ProductCategoryID INNER JOIN Production.Product AS P ON P.ProductSubcategoryID = PSC.ProductSubcategoryID WHERE PSC.Name LIKE '%Bike%' ORDER BY [Nombre de Subcategoria] ;
Una vez ms, se utiliza una combinacin interna, porque slo las filas en comn entre las tres tablas necesitan ser recuperados Resumen Cuando se utilizan JOIN se deben tomar en cuenta algunas consideraciones: - Especificar las condiciones del JOIN en base a Primary Key (PK) y a Foreign Key (FK) - Si una tabla tiene una PK compuesta, se debe referenciar a la clave entera en la clusula ON del JOIN - Las tablas comunes a las tablas deben ser del mismo tipo de dato - La clusula JOIN permite recuperar columnas de tablas relacionadas - Los operadores JOIN pueden combinar ms de una tabla. - JOIN puede incluir INNER, LEFT OUTER, RIGHT OUTER y FULL OUTER - Una tabla puede ser combinada consigo misma definiendo diferentes alias