martes, 7 de junio de 2016

Receta T-SQL No. 4-7: ¿Cómo Comprobar la Existencia de un Registro?

Índice

1. Introducción
2. Palabras Clave
3. Problema
4. Solución
5. Discusión de la Solución
5.1 Consulta correlacionada
5.2 Predicado EXISTS
6. Práctica: Comprobar la Existencia de un Registro
7. Conclusiones
8. Literatura & Enlaces

1. Introducción

En la receta anterior se hizo uso de una subconsulta anidada para realizar un INNER JOIN entre dos tablas. El propósito funcional consistía en efectuar un SELECT sobre los resultados devueltos por esa subconsulta y así proceder a hacer un INNER JOIN. En esta ocasión se usa un enfoque alternativo que en esencia comprueba la existencia de un registro de una tabla frente a otra. Aquí el contraste se realiza frente una subconsulta correlacionada a través del predicado EXISTS.

2. Palabras Clave

  • EXISTS
  • Predicado
  • Registro
  • Subconsulta
  • Subconsulta correlacionada

3. Problema

Recuperar los registros de un tabla consultada frente a otros registros relacionados en una tabla distinta.

4. Solución

T-SQL cuenta con el predicado EXISTS para comprobar la existencia de registros frente a una tabla consultada exterior.

5. Discusión de la Solución

5.1 Consulta correlacionada

De acuerdo con "Correlated subquery" (2016) una consulta correlacionada es una subconsulta que usa valores de una consulta exterior. Por ejemplo en 

SELECT NoEmpleado, NombreEmpleado 
    FROM Empleados E
        WHERE Salario > (
            SELECT AVG(Salario)
                FROM Empleados
                    WHERE Departamento = E.Departamento);

Nótese cómo el salario para cada empleado en Empleados es comparado con el promedio de salarios de los empleados que pertenecen al mismo departamento de E.

La consulta exterior en este ejemplo comprende

SELECT NoEmpleado, NombreEmpleado 
    FROM Empleados E
        WHERE Salario > ...

y la consulta interior -i.e., consulta correlacionada- corresponde a 

SELECT AVG(Salario)

    FROM Empleados
        WHERE Departamento = E.Departamento

Esta subconsulta se ha de ejecutar por cada empleado E de la consulta exterior. (Es importante considerar para este tipo de consultas el efecto sobre el desempeño de la ejecución del proceso que le invoca, debido al consumo, posiblemente, excesivo de recursos de máquina -tiempo de procesador y espacio de memoria-.)

5.2 Predicado EXISTS

Con el predicado EXISTS ("EXISTS (Transact-SQL)", 2016) se especifica una comprobación de existencia de registros en una subconsulta.

Esta es su sintaxis: 

EXISTS subconsulta

Ejemplo de uso

SELECT a.FirstName AS 'Primer Nombre',
a.LastName AS 'Apellido'
FROM Person.Person AS a
WHERE EXISTS (SELECT *
FROM HumanResources.Employee AS b
WHERE a.BusinessEntityID = b.BusinessEntityID
AND a.LastName = 'Johnson');

Con esta sentencia se retornan todos las personas -Person- que son empleados -a.BusinessEntity = b.BusinessEntityID- y que tienen como apellido 'Johnson'.

Este es el resultado de la ejecución de esta sentencia T-SQL
Uso de EXISTS
Figura 1. Uso de EXISTS.

6. Práctica: Comprobar la Existencia de un Registro

En el siguiente ejemplo se recuperan todas las órdenes -SalesOrderHeader- que contengan un precio unitario -UnitPrice- entre 1000 y 2000, y que su SalesOrderID se igual al SalesOrderID de la tabla de detalles de la orden de venta -Sales.SalesOrderDetail-:

SELECT DISTINCT
s.PurchaseOrderNumber AS 'No. Orden Compra'
FROM Sales.SalesOrderHeader AS s
WHERE EXISTS (SELECT SalesOrderID
FROM Sales.SalesOrderDetail
WHERE UnitPrice BETWEEN 1000 AND 2000
AND SalesOrderID = s.SalesOrderID);

El resultado generado por esta consulta en Microsoft SQL Server Management Studio es:
Comprobación existencia registro con consulta correlacionada
Figura 2. Comprobación existencia registro con consulta correlacionada.
Si se observa con cuidado, los resultados generados son equivalentes a los de la consulta 

SELECT DISTINCT s.PurchaseOrderNumber AS 'No. Orden Compra'
FROM Sales.SalesOrderHeader s
INNER JOIN (SELECT SalesOrderID
FROM Sales.SalesOrderDetail
WHERE UnitPrice BETWEEN 1000 AND 2000
) d
ON s.SalesOrderID = d.SalesOrderID;

definida en Receta T-SQL No. 4-6: ¿Cómo Hacer una Selección a Partir de un Conjunto de Resultados? Es decir que se tienen dos enfoques para resolver la misma consulta; sin embargo, el programador debe ser cuidadoso entre cuál de los dos escoger dado que en distintos escenarios el rendimiento puede variar considerablemente dependiendo de la complejidad de la consulta y otros factores -volumen de datos a consultar, implementación de índices, etcétera-.

7. Conclusiones

Esta receta demostró el uso del predicado EXISTS para la composición de consultas correlacionadas. Se dejó claro que el uso de este tipo de consultas puede tener un efecto positivo o negativo en el rendimiento dependiendo de factores como la complejidad de la consulta o el volumen de los datos.

8. Literatura & Enlaces

Brimhall, J., Dye, D., Gennick, J., Roberts, A., Sheffield, W. (2012). SQL Server 2012 T-SQL Recipes - A Problem-Solution Approach. United States: Apress.
Correlated subquery (2016, junio 7). Recuperado desde: https://en.wikipedia.org/wiki/Correlated_subquery
EXISTS (Transact-SQL) (2016, junio 7). Recuperado desde: https://msdn.microsoft.com/en-us/library/ms188336.aspx?f=255
Receta T-SQL No. 4-6: ¿Cómo Hacer una Selección a Partir de un Conjunto de Resultados? (2016, junio 7). Recuperado desde: http://ortizol.blogspot.com/2016/06/receta-t-sql-no-4-6-como-hacer-una-seleccion-a-partir-de-un-conjunto-de-resultados.html


V

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.