jueves, 30 de junio de 2016

Receta T-SQL No. 4-11: ¿Cómo Eliminar Duplicados en una Unión?

Índice

1. Introducción
2. Palabras Clave
3. Problema
4. Solución
5. Discusión de la Solución
5.1 Operador UNION
6. Práctica: Listar los Apellidos de Empleados y Vendedores sin Duplicados
7. Conclusiones
8. Literatura & Enlaces

1. Introducción

Se ha comprendido que a través del operador UNION ALL se obtienen los registros de dos o más tablas, aun duplicados. Existe en T-SQL otro operador para realizar uniones de registros pero sin duplicados: UNION. En esta receta se presenta un caso de ejemplo donde resulta útil este operador: generar un reporte de los apellidos de todos los empleados y vendedores de una compañía.

2. Palabras Clave

  • Operador
  • UNION
  • UNION ALL

3. Problema

Generar reporte de todos los apellidos de empleados y vendedores de una compañía.

4. Solución

En T-SQL el operador UNION combina los resultados de dos o más consultas y elimina duplicados.

5. Discusión de la Solución

5.1 Operador UNION

El operador UNION combina los resultados de dos o más consultas en un único conjunto de resultados ("UNION (Transact-SQL", 2016). A diferencia de UNION ALL, UNION remueve los duplicados de la unión/combinación.


Para efectuar la combinación/unión de resultados se deben seguir estas reglas: 
  • El orden y número de las columnas de las consultas debe ser el mismo.
  • Los tipos de datos de las columnas debe ser compatible.
Sintaxis: 

{ consulta_1 }
UNION
{consulta_2
[ UNION
{consulta_n}
]

6. Práctica: Listar los Apellidos de Empleados y Vendedores sin Duplicados

Este ejemplo en T-SQL ilustra cómo obtener un listado o reporte de los apellidos de empleados y vendedores sin duplicados a través del uso del operador UNION.

En las líneas 1-4 se recuperan todos los apellidos de las personas que son empleados. Este resultado se combina con la sentencia SELECT que recupera los apellidos de las personas que son vendedores (líneas 6-9).


Este es el resultado que se obtiene de ejecutar la sentencia en Microsoft SQL Management Studio
Apellidos de personas que son vendedores o empleados
Figura 1. Apellidos de personas que son vendedores o empleados.

7. Conclusiones

El operador UNION permite obtener registros -no repetidos- de la unión de dos o más sentencias SELECT. Quedó claro que se debe seguir el orden y número de campos, además de la coincidencia con tipos de datos compatibles.


La próxima receta T-SQL se concentra en demostrar cómo sustraer un registro de un conjunto de otro distinto.

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.
UNION (Transact-SQL) (2016, junio 30). Recuperado desde: https://msdn.microsoft.com/en-us/library/ms180026.aspx


V

miércoles, 29 de junio de 2016

Receta T-SQL No. 4-10: Combinar los Resultados de Dos o Más Sentencias SELECT

Índice

1. Introducción
2. Palabras Clave
3. Problema
4. Solución
5. Discusión de la Solución
5.1 Operador UNION ALL
6. Práctica: Combinación Cuotas Actuales e Históricas
7. Conclusiones
8. Literatura & Enlaces

1. Introducción

A través de esta receta T-SQL el programador aprenderá a combinar los resultados de dos o más sentencias SELECT a través del uso del operador UNION ALL. Este tipo de operación puede resultar útil para combinar datos repetidos en tablas diferentes; por ejemplo cuotas de ventas a lo largo del tiempo y actuales.

2. Palabras Clave

  • Combinación
  • Registro
  • UNION
  • UNION ALL

3. Problema

Combinar los registros de dos sentencias SELECT.

4. Solución

El operador UNION ALL permite combinar registros de dos o más tablas.

5. Discusión de la Solución

5.1 Operador UNION ALL

El operador UNION ALL se usa para combinar los registros de dos o más sentencias SELECT. Esta es su sintaxis: 

SELECT expresion_1, expresion_2, ..., expresion_n
FROM tabla
[WHERE condiciones]
UNION ALL
SELECT expresion_1, expresion_2, ..., expresion_n
FROM tabla
[WHERE condiciones]

Este operador no elimina registros duplicados recuperados por cada una de las sentencias SELECT. Otro requerimiento consiste en que cada sentencia SELECT debe tener el mismo número expresiones (i.e., campos) y un tipo de dato similar.

Un ejemplo particular puede consistir en las tablas: 
Tabla Proveedores
Figura 1. Tabla Proveedores.
Tabla Órdenes
Figura 2. Tabla Órdenes.
Al ejecutar una sentencia T-SQL como esta 

SELECT id_proveedor
FROM Proveedores
UNION ALL
SELECT id_proveedor
FROM Ordenes
ORDER BY id_proveedor

se obtiene 
UNION ALL de Proveedores y Ordones
Figura 3. UNION ALL de Proveedores y Ordones.
Aquí se puede observar cómo se repite el valor 2000; esto porque está presente en ambas tablas y el operador UNION ALL no remueve registros duplicados.

6. Práctica: Combinación Cuotas Actuales e Históricas

Este ejemplo enseña cómo combinar cuotas de ventas: actuales e históricas.

La declaración del primer SELECT (líneas 1-5) especifica: 
  • Recuperación de tres valores: identidad del vendedor -desde Sales.SalesPerson-, fecha actual (nótese cómo ha sido renombrada; las funciones no generan un nombre), y la cuota de ventas.
  • La cuota de ventas debe ser mayor a 0 (línea 5).
En cuanto a la sentencia SELECT que viene a continuación del operador UNION ALL, se tiene 
  • Recuperación de valores análogos -en cuanto a número y tipos de datos- a los del primer SELECT.
  • El historial de la cuota de ventas también debe ser mayor a 0 (línea 11).
  • Aquí se consulta la tabla Sales.SalesPersonQuotaHistory.
Hay que resaltar que esta sentencia cumple los requisitos básicos para poder aplicar el operador UNION ALL:
  1. Número y tipo de datos análogos.
  2. Sentencia ORDER BY al final de la sentencia.
Es el momento de ejecutar esta sentencia en Microsoft SQL Management Studio
UNION ALL SalesPerson y SAlesPersonQuotaHistory
Figura 4. UNION ALL entre SalesPerson y SalesPersonQuotaHistory.

7. Conclusiones

Esta receta demostró cómo combinar los registros de dos tablas que contienen datos relacionados -cuotas de ventas actuales e históricos, por ejemplo- a través del operador UNION ALL.

En la próxima receta T-SQL se demostrará cómo eliminar valores duplicados en una unión de registros.

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.
SQL: UNION ALL Operator (2015, junio 29). Recuperado desde: http://www.techonthenet.com/sql/union_all.php


V

martes, 28 de junio de 2016

Receta T-SQL No. 4-9: ¿Cómo Comparar Subconjuntos de Datos de una Tabla?

Índice

1. Introducción
2. Palabras Clave
3. Problema
4. Solución
5. Discusión de la Solución
5.1 Jerarquía anidada
5.2 Alias para el nombre de una tabla
6. Práctica: Comparación de Subconjuntos de Datos de una Tabla
7. Conclusiones
8. Literatura & Enlaces

1. Introducción

En la definición del esquema de una base datos, el diseñador puede definir jerarquías anidadas de datos en una tabla. Este tipo de jerarquías permite, por ejemplo, por medio de un JOIN referenciar subconjuntos de datos y en consecuencia efectuar operaciones entre los registros de una misma tabla. En esta receta T-SQL se enseña cómo a través del renombramiento de tablas, operaciones del tipo JOIN sobre una sola tabla son posibles.

2. Palabras Clave

  • Base de datos
  • Esquema
  • Jerarquía anidada
  • JOIN
  • Subconjunto de datos
  • Tabla

3. Problema

Efectuar una operación JOIN sobre un subconjunto de datos de una tabla.

4. Solución

A través del renombramiento -i.e., alias- varias jerarquías anidadas de datos pueden estar presentes en una operación JOIN.

5. Discusión de la Solución

5.1 Jerarquía anidada


Una jerarquía anidada se define como una estructura integral de una entidad de datos -i.e., tabla o relación- con la que se determinan relaciones entre los datos de esa misma entidad. Por enunciar un ejemplo, el lector puede pensar en la clásica entidad Empleado: en una organización cada empleado está a cargo de un jefe y éste al mismo tiempo es un empleado; en vista gráfica se tendría: 
Jerarquía anidada Empleado-Jefe
Figura 1. Jerarquía anidada Empleado-Jefe.
En este caso el campo id_jefe es la llave foránea con la que se construye la relación «un empleado tiene un jefe».

Con este tipo de relación una tabla puede tratarse como dos tablas independientes o separadas, y realizar consultas acorde a las relaciones que puedan establecerse. Otro tipo de ejemplo constituye las clases de tablas que registran períodos de tiempo: periodos de venta, producción, actividad de transacciones, etc.

5.2 Alias para el nombre de una tabla

(Nota: En Receta T-SQL No. 1-7: Creación de un Alias para el Nombre de una Tabla se describe en detalle cómo renombrar o crear un alias para una tabla.)

6. Práctica: Comparación de Subconjuntos de Datos de una Tabla

El código T-SQL que viene a continuación renombra la tabla Sales.SalesPersoQuotaHistory dos veces; esto con el el propósito de totalizar las ventas de un vendedor para dos años distintos: 2008 y 2009.

En primer lugar se escribe 

FROM Sales.SalesPerson AS S

para obtener las identidades de los vendedores. Luego con 

LEFT OUTER JOIN Sales.SalesPersonQuotaHistory AS S2008
ON S.BusinessEntityID = S2008.BusinessEntityID
AND YEAR(S2008.QuotaDate) = 2008

se obtiene todos los registros de ventas para el año 2008.


A continuación se efectúa otro LEFT OUTER JOIN con la misma tabla pero para el período 2007 y los mismos vendedores:

LEFT OUTER JOIN Sales.SalesPersonQuotaHistory AS S2007
ON S.BusinessEntityID = S2007.BusinessEntityID
AND YEAR(s2007.QuotaDate) = 2007


Al unir estos fragmentos de código, se tiene 

Archivo T-SQL JerarquíaAnidada.sql [Enlace alternativo][Enlace alternativo]: 

Estos son los resultados obtenidos en Microsoft SQL Server Managamente Studio:
Jerarquía anidada SalesPersonQuotaHistory-PeriodoVentas
Figura 2. Jerarquía anidada SalesPersonQuotaHistory-PeriodoVentas.

7. Conclusiones

Se ha demostrado que una jerarquía de datos resulta de interés para la extracción de datos relevantes en una única relación: como la de Empleado-Jefe o la demostrado en el ejemplo de Sales.SalesPersonQuotaHistory.

La siguiente receta T-SQL describe y enseña a combinar los conjuntos de datos de dos relaciones.

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.
Receta T-SQL No. 1-7: Creación de un Alias para el Nombre de una Tabla (2016, junio 28). Recuperado desde: https://ortizol.blogspot.com.co/2014/07/receta-t-sql-no-1-7-creacion-de-un-alias-para-el-nombre-de-una-tabla.html


V

lunes, 27 de junio de 2016

Receta Multithreading en C# No. 5-3: Uso Operador await en Tareas Asincrónicas Subsecuentes

Índice

1. Introducción
2. Palabras Clave
3. Problema
4. Solución
5. Discusión de la Solución
5.1 Implementación con TPL
5.2 Implementación con el operador asincrónico async
6. Práctica: TPL vs Operador Asincrónico await en Tareas Asincrónicas
Conclusiones
Literatura & Enlaces

1. Introducción

Es momento de comprender qué ocurre con las llamadas consecutivas a tareas asincrónicas con el operador asincrónico await. Esta receta explica la forma de leer el flujo de control de invocaciones de operaciones asincrónicas tanto de una implementación con TPL y otra con el operador asincrónico await para finalmente concluir cuál de los dos enfoques es el más práctico.

2. Palabras Clave

  • Asincronismo
  • await
  • Flujo de control
  • Operador asincrónico
  • Sincronismo
  • TPL

3. Problema

Analizar el flujo de control de tareas asincrónicas subsecuentes tanto con el enfoque de TPL y uso del operador asincrónico await.

4. Solución

Para la solución de este problema se escriben dos métodos:
  1. Con construcciones de TPL -objetos Task y continuaciones.
  2. Con operador asincrónico await.

5. Discusión de la Solución

5.1 Implementación con TPL

Para definir una implementación con TPL se recurre al uso de continuaciones a partir de una tarea compuesta. Esta tarea compuesta cuenta con declaraciones de otro objetos Task anidadas, que al mismo tiempo definen un esquema de respuesta a casos de éxito y fallo a través de continuaciones.

5.2 Implementación con el operador asincrónico await

Este operador simplifica la invocación de operaciones asincrónicas usando elementos del lenguaje para la obtención de resultados, gestión de excepciones y el flujo de control del programa.

6. Práctica: TPL vs Operador Asincrónico await en Tareas Asincrónicas Subsecuentes

Este ejemplo es una adaptación del código presentado por Aganof (2016): presenta una implementación del flujo de control de operaciones asincrónicas en TPL y con la función asincrónica await.

El método ObtenerInfoThreadAsync(string) (líneas 86-103) lleva a cabo las siguientes operaciones: 
  • Línea 88: Muestra el nombre de la fuente desde donde se invocó este método.
  • Línea 91: Simula la ejecución de una operación de duración extendida.
  • Líneas 93-96: Lanza una excepción intencionada cuando el nombre de la fuente es "TPL No. 2".
  • Líneas 98-102: Retorna información del thread de ejecución para esta operación asincrónica.
Método AsincronismoConTpl() (líneas 26-58): 
  • Líneas 28-53: Definición de tarea compuesta.
    • Línea 30: Definición y asociación de objeto Task con el método ObtenerInfoThreadAsync().
    • Líneas 35-44: Definición de un nuevo objeto Task anidado, además de continuaciones para los casos de éxito y excepción.
    • Líneas 49-52: Continuación para objeto Task tarea1.
  • Línea 55: Inicio de la ejecución de la tarea compuesta.
Método AsincronismoConAwait() (líneas 65-78): 
  • Líneas 67-73: Bloque try para la invocación lineal/sincrónica de ObtenerInfoThreadAsync() a través del operador asincrónico await.
  • Líneas 74-77: Bloque catch para responder a excepciones que eventualmente se produzcan durante la ejecución de las operaciones invocadas con await.
Hay que notar que en el caso de AsincronismoConAwait() ambas invocaciones se realizarán una tras otra, es decir de modo secuencial -i.e., sincrónicamente. Mientras que en AsincronismoConTpl() se requiere de una mayor complejidad -tareas anidadas, continuaciones y definiciones para responder a casos de falla y éxito.

Otro punto relevante en este caso es que el programa da la impresión de tratarse de una implementación de sincronismo, sin embargo al remover las llamadas a Wait() en el método Ejecutar() (líneas 12-19), se puede pensar que las llamadas a AsincronismoConAwait() y AsincronismoConTpl() son tareas asincrónicas y que Ejecutar() puede ejecutar otras expresiones mientras que éstos dos terminan. Wait() sólo se ha usado en este caso para demostrar la diferencia de implementación de estos dos enfoques.

La siguiente captura de vídeo demuestra lo que sucede con la invocación de los dos métodos anterior: 


En este enlace de GitHub puede encontrar la solución de Visual Studio 2015 y los proyectos asociados a esta receta y otras más: https://github.com/Fhernd/RecetasMultithreadingCSharp.

7. Conclusiones

Se demostró que una implementación de una operación asincrónico con el operador asincrónico await es mucho más elegante e intuitiva frente a una creada usando elementos de programa de TPL.

En la próxima receta multithreading se mostrará al programador cómo usar await en la ejecución en paralelo de operaciones asincrónicas.

8. Literatura & Enlaces

Agafonov, E. (2013). Multithreading in C# 5.0 Cookbook. United States: Packt Publishing.

V