lunes, 29 de febrero de 2016

Combinación de Conjuntos - Usando Operadores de Conjunto

Los operadores de conjunto operan sobre dos conjuntos de resultados de consultas, comparando filas completas entre los resultados. Dependiendo del resultado de la comparación y del operador de conjunto utilizado, el operador determina si retornar la fila o no. T-SQL soporta tres operadores de conjunto: UNION, INTERSECT, y EXCEPT; también soporta un operador multiconjunto: UNION ALL.
La forma general de código usando un operador de conjunto es como sigue.
<consulta 1>
<operador conjunto>
<consulta 2>
[ORDER BY <lista_order_by>]
Trabajar con operadores de conjunto sigue una serie de pautas:
·         Debido a que las filas completas son emparejadas entre los conjuntos de resultados, el número de columnas en las consultas tiene que ser el mismo y los tipos de columna de las columnas correspondientes necesitan ser compatibles (convertibles implícitamente).
·         Los operadores de conjunto consideran dos NULLs como iguales para propósitos de comparación. Esto es bastante inusual cuando es comparado con las cláusulas de filtrado como WHERE y ON.
·         Debido a que los operadores son operadores de conjunto y no operadores de cursor, a las consultas individuales no se les permite que tengan cláusulas ORDER BY.
·         Puede opcionalmente agregar una cláusula ORDER BY que determina el orden de presentación del resultado del operador de conjunto.
·         Los nombres de columna de las columnas de resultado están determinados por la primera consulta.

UNION y UNION ALL

El operador de conjuntos UNION unifica los resultados de las dos consultas de entrada. Como un operador de conjunto, UNION tiene una propiedad DISTINCT implícita, significando que no retorna las filas duplicadas. La figura muestra una ilustración del operador UNION, utilizando un diagrama de Venn. 
Como un ejemplo por utilizar el operador UNION, la siguiente consulta retorna locaciones que son ubicaciones de empleados o ubicaciones de clientes, o ambos.
SELECT country, region, city
FROM HR.Employees
UNION
SELECT country, region, city
FROM Sales.Customers;
Esta consulta genera la siguiente salida, mostrada aquí en forma abreviada.
country         region           city
--------------- --------------- ---------------
UK              NULL             London
USA             WA               Kirkland
USA             WA               Seattle
...
(71 filas afectadas)
La tabla HR.Employees tiene 9 filas y la tabla Sales.Customers tiene 91 filas, pero hay 71 lugares distintos en los resultados unificados; por lo tanto, el operador UNION retorna 71 filas.
Si desea mantener los duplicados; por ejemplo, para más adelante agrupar las filas y contar las ocurrencias, necesita utilizar el operador multiconjunto UNION ALL en lugar de UNION. El operador UNION ALL unifica los resultados de las dos consultas de entrada, pero no trata de eliminar los duplicados. La figura tiene una ilustración del operador UNION ALL utilizando un diagrama de Venn. 
A modo de ejemplo, la siguiente consulta unifica ubicaciones de empleados y ubicaciones de clientes utilizando el operador UNION ALL.
SELECT country, region, city
FROM HR.Employees
UNION ALL
SELECT country, region, city
FROM Sales.Customers;
Debido a que UNION ALL no intenta eliminar los duplicados, el resultado tiene 100 filas (9 de empleados + 91 de clientes).
country         region           city
--------------- --------------- ---------------
USA             WA              Seattle
USA             WA               Tacoma
USA             WA               Kirkland
USA             WA               Redmond
UK              NULL             London
UK              NULL             London
UK              NULL             London
...
(100 filas afectadas)
Importante: UNION versus UNION ALL
Si los conjuntos que está unificando son disjuntos y no hay posibilidad de duplicados, UNION y UNION ALL retornaran el mismo resultado. Sin embargo, es importante utilizar UNION ALL en ese caso, desde el punto de vista de rendimiento, ya que con UNION, SQL Server puede tratar de eliminar los duplicados, incurriendo en costos innecesarios.

INTERSECT

El operador INTERSECT sólo retorna las filas distintas que son comunes a ambos conjuntos. En otras palabras, si una fila aparece al menos una vez en el primer conjunto y al menos una vez en el segundo conjunto, aparecerá una vez en el resultado del operador INTERSECT. La figura ilustra el operador INTERSECT utilizando un diagrama de Venn. 
A modo de ejemplo, el código siguiente utiliza el operador INTERSECT para retornar ubicaciones distintas que son ubicaciones de empleados y de clientes (ubicaciones donde hay al menos un empleado y al menos un cliente).
SELECT country, region, city
FROM HR.Employees
INTERSECT
SELECT country, region, city
FROM Sales.Customers;
Esta consulta genera el siguiente resultado.
country         region           city
--------------- --------------- ---------------
UK              NULL             London
USA             WA               Kirkland
USA             WA               Seattle
Observe que la ubicación (UK, NULL, London) fue retornado porque aparece en ambos lados. Cuando compara los NULLs en la columna region en las filas de los dos lados, el operador INTERSECT los considera como iguales. También note que no importa cuántas veces aparece la misma ubicación en cada lado, siempre que aparece al menos una vez en ambos lados, es retornado sólo una vez en la salida.

EXCEPT

El operador EXCEPT realiza diferencias de conjuntos. Retorna filas distintas que aparecen en la primera consulta, pero no la segunda. En otras palabras, si una fila aparece al menos una vez en la primera consulta y cero veces en la segunda, es retornado una vez en la salida. La figura ilustra el operador EXCEPT con un diagrama de Venn. 
Como ejemplo del uso de EXCEPT, la siguiente consulta retorna las ubicaciones que son ubicaciones de empleados, pero no ubicaciones de clientes.
SELECT country, region, city
FROM HR.Employees
EXCEPT
SELECT country, region, city
FROM Sales.Customers;
Esta consulta genera el siguiente resultado.
country         region           city
--------------- --------------- ---------------
USA             WA               Redmond
USA             WA               Tacoma
Con UNION e INTERSECT, el orden de las consultas de entrada no importa. Sin embargo, con EXCEPT, hay un diferente significado para <consulta 1> EXCEPT <consulta 2> versus <consulta 2> EXCEPT <consulta 1>.
Por último, los operadores de conjunto tienen precedencia: INTERSECT precede a UNION y EXCEPT, y UNION y EXCEPT son considerados iguales. Considere los siguientes operadores de conjunto.
<consulta 1> UNION <consulta 2> INTERSECT <consulta 3>;
En primer lugar, la intersección entre la consulta 2 y la consulta 3 tiene lugar, y luego una unión entre el resultado de la intersección y consulta 1. Siempre puede forzar la precedencia por utilizar paréntesis. Por lo tanto, si desea que la unión tenga lugar primero, utilice la forma siguiente.
(<consulta 1> UNION <consulta 2>) INTERSECT <consulta 3>;

Ejercicio 1: Utilice el Operador de Conjunto EXCEPT

En este ejercicio, practica la identificación de relaciones entre clientes y empleados a través de pedidos utilizando el operador de conjunto EXCEPT.
1.    Abra el SSMS y conéctese a la base de datos de muestra TSQL2012.
2.    Escriba una consulta que retorna los empleados que manejaron pedidos para el cliente 1, pero no para el cliente 2. Para ello, utilice el operador de conjunto EXCEPT, de la siguiente manera.
SELECT empid
FROM Sales.Orders
WHERE custid = 1
EXCEPT
SELECT empid
FROM Sales.Orders
WHERE custid = 2;
La primera consulta retorna los empleados que manejan los pedidos del cliente 1, y la segunda consulta retorna los empleados que manejan los pedidos del cliente 2. Debido a que el operador EXCEPT es utilizado entre la primera y la segunda consulta, obtiene los empleados que manejan los pedidos del cliente 1, pero no del 2, conforme a lo solicitado. Recuerde que EXCEPT no retorna filas duplicadas, por lo que no necesita preocuparse por un empleado que aparezca más de una vez en la salida. Su código solución retorna los siguientes empleados.
empid
-----------
1
6

Ejercicio 2: Utilice el Operador de Conjunto INTERSECT

En este ejercicio, practica la identificación de las relaciones entre los clientes y los empleados a través de pedidos utilizando el operador de conjunto INTERSECT.
Utilizando la misma tabla Sales.Orders que utilizó en el ejercicio 1, retorna empleados que manejaron pedidos, tanto para el cliente 1 y para el cliente 2. Para lograr esto, utilice las mismas dos consultas de entrada, pero esta vez intersecte los resultados utilizando el operador INTERSECT, de la siguiente manera.
SELECT empid
FROM Sales.Orders
WHERE custid = 1
INTERSECT
SELECT empid
FROM Sales.Orders
WHERE custid = 2;
Este código devuelve la siguiente salida.
empid
-----------
3
4

1 comentario:

  1. Este post trata de Combinación de Conjuntos - Usando Operadores de Conjunto. Espero les sea de utilidad.

    ResponderBorrar