Mostrando entradas con la etiqueta Data base. Mostrar todas las entradas
Mostrando entradas con la etiqueta Data base. Mostrar todas las entradas

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

jueves, 7 de abril de 2016

Receta T-SQL No. 4-1: ¿Cómo Correlacionar dos Tablas?

Índice

1. Introducción
2. Palabras Clave
3. Problema
4. Solución
5. Discusión de la Solución
5.1 INNER JOIN
6. Práctica: Correlación de las Tablas Person y PersonPhone
7. Conclusiones
8. Literatura & Enlaces

1. Introducción

Con esta receta T-SQL se inicia la serie de recetas enfocadas a la creación de consultas sobre múltiples tablas. Una base de datos está constituida por varias tablas que relacionan los tipos de datos para un dominio de problema; cada tabla mantienen en óptimo estado el almacenamiento de los datos; además de su consistencia e integridad. T-SQL ofrece un conjunto de operadores para especificar las consultas sobre múltiples tablas: la información obtenida permite responder a requerimientos de negocio: los empleados y su sueldo, los pedidos de un cliente, los vuelos realizados por un pasajero, etc. Entre esos operadores se cuentan aquellos que permiten ejecutar operaciones como: joins, uniones, y subconsultas.


En esta primera receta T-SQL se muestra cómo correlacionar datos de distintas tablas. Para esto es necesario el uso del operador INNER JOIN, el cual, como se muestra en la sección práctica, permite la correlación de los datos de dos tablas: Person y PersonPhone.

2. Palabras Clave

  • Consistencia
  • Correlación
  • INNER JOIN
  • Integridad
  • Producto cartesiano
  • Subconsulta
  • Tabla

3. Problema

Obtener las personas que tienen por lo menos un número telefónico asociado. Además, indicar por persona los números de cada línea telefónica.

4. Solución

En T-SQL se cuenta con el operador INNER JOIN para correlacionar los registros de dos tablas.

5. Discusión de la Solución

5.1 INNER JOIN

El operador INNER JOIN permite correlacionar dos tablas bajo una condición de correlación -normalmente una llave primaria o un campo con valores en común-. El resultado de la es una tabla que contiene los registros correlacionados del producto cartesiano de las tablas.

Esta es la sintaxis (versión simplificada) para este operador:

SELECT {Proyección de Columnas} 
    FROM {TABLA_1} INNER JOIN {TABLA_2} 
        ON {TABLA_1}.Columna = {TABLA_2}.Columna
    WHERE {Condiciones}

Nótese que frente a la cláusula ON se especifican las columnas bajo las que se correclacionan las tablas a través del operador relacional =.

6. Práctica: Correlación de las Tablas Person y PersonPhone

Este ejemplo (adaptado de Brimhall (2012)) correlaciona dos tablas: 
  • Person y 
  • PersonPhone
de la base de datos AdventureWorks. Se obtendrá el conjunto de personas que tienen por lo menos una línea teléfono junto con los números asociados a cada una de ellas.

SELECT H.BusinessEntityID AS 'Identificación',
FirstName AS 'Primer Nombre',
LastName AS 'Apellido',
PhoneNumber AS 'Número Telefónico'
FROM Person.Person P INNER JOIN Person.PersonPhone H
ON P.BusinessEntityID = H.BusinessEntityID
ORDER BY LastName, FirstName, P.BusinessEntityID;

En este caso el operador INNER JOIN relaciona dos tablas -Person y PersonPhone- (cada una de estas tablas está renombrada para facilitar su referencia en la proyección y correlación). En la cláusula ON se especifican las dos columnas a comparar:

ON P.BusinessEntityID = H.BusinessEntityID

El resultado se ordena por apellido, primer nombre, y el identificador de la persona.

En Microsoft SQL Server Management Studio se ejecuta el código anterior y se obtienen los siguientes registros (versión compacta con 25 registros):
Correlación Person y PersonPhone
Figura 1. Correlación Person y PersonPhone.

7. Conclusiones

Con el operador INNER JOIN de T-SQL se correlacionan dos tablas a partir de la relación de igualdad entre dos columnas de cada tabla. El ejemplo de la sección 6 presentó cómo obtener el conjunto de personas que poseen por lo menos una línea telefónica, además de los números asociados a cada una. Este tipo de operación facilita responder a requerimientos de negocio sobre los tipos de relaciones que mantienen los tipos de datos de un dominio de problema.

La próxima receta T-SQL enseña cómo diseñar una consulta sobre una relación muchos-a-muchos.

8. Literatura & Enlaces

Brimhall, J., Dye, D., Gennick, J., Roberts, A., Sheffield, W. (2012). SQL Server 2012 T-SQL Recipes - A Problem-Solucion Approach. United States: Apress.
Using Joins (2016, abril 7). Recuperado desde: https://msdn.microsoft.com/en-us/library/ms191472.aspx


V

viernes, 4 de diciembre de 2015

Receta T-SQL No. 3-6: Forzar la Unicidad de una Columna con NULL

Índice

1. Introducción
2. Palabras Clave
3. Problmea
4. Solución
5. Discusión de la Solución
5.1 Índice único -unique index-
6. Práctica: Código T-SQL
7. Conclusiones
8. Literatura & Enlaces

1. Introducción

Esta nueva receta Transact-SQL enseña a utilizar un mecanismo para asegurar la unicidad de una columna que admita NULL. Se demuestra en primera instancia que un índice único -unique index- evita duplicados tanto de valores concretos para un tipo de dato específico como de valores desconocidos NULL. Esto es posible a través de la creación de un índice único nonclustered, el cual permite la unicidad de valores concretos y multiplicidad o asignación de NULL a múltiples registros para el mismo campo.

2. Palabras Clave

  • Índice
  • Índice único
  • Multiplicidad
  • Unicidad
  • Nonclustered index

3. Problema

Permitir que una columna de una tabla pueda contener valores concretos únicos de un tipo de dato específico. Además que se permitan múltiples valores NULL.

4. Solución

Usar un índice no-agrupado o nonclustered para el campo que debe cumplir el requerimiento de unicidad para valores concretos y multiplicidad para valores no conocidos o NULL.

5. Discusión de la Solución

5.1 Índice único -unique index-

Un índice único (o unique index) es un tipo de índice que garantiza la unicidad o no duplicado de valores para un campo o columna llave ("Create Unique Indexes", 2015). Además, este tipo de índice puede involucrar varias columnas. Por ejemplo se puede crear un índice para un número de teléfono para un requerimiento de negocio que especifique que cada cliente debe tener uno o más números de teléfono distintos a cualquiera de los demás clientes.

Lo anterior también aplica para una combinación de columnas como PrimerNombre, SegundoNombre, Apellidos. En el índice único no puede existir más de un registro que tenga la misma combinación de primer nombre, segundo nombre y apellidos.

Otro propósito interesante de este clase de índice es garantizar la integridad de datos sobre la o las columnas que forman parte del índice. Además, como se manifiesta en "Create Unique Indexes" (2015), un índice único facilita información extra para el optimizador de consultas de SQL Server.

6. Práctica: Código T-SQL

Creación de tabla Producto:

CREATE TABLE Producto
(
IdProducto INT NOT NULL
CONSTRAINT PK_Producto PRIMARY KEY CLUSTERED,
NombreProducto NVARCHAR(50) NOT NULL,
NombreClave NVARCHAR(50)
);

A coninuación se ha de crear el índice único nonclustered:

CREATE UNIQUE INDEX UX_Producto_NombreClave ON Producto(NombreClave);

A partir de aquí se prueba con la inserción de registros en la misma tabla:

INSERT INTO Producto (IdProducto, NombreProducto, NombreClave)
VALUES (1, 'Producto #1', 'Adven');

INSERT INTO Producto (IdProducto, NombreProducto, NombreClave)
VALUES (2, 'Producto #2', 'Fomich');

INSERT INTO Producto (IdProducto, NombreProducto, NombreClave)
VALUES (3, 'Producto #3', NULL);

INSERT INTO Producto (IdProducto, NombreProducto, NombreClave)
VALUES (4, 'Producto #4', NULL);

Al intentar ejecutar esas sentencias de inserción de registros se genera un mensaje de error para la última:

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)
Msg 2601, Level 14, State 1, Line ...
Cannot insert duplicate key row in object 'dbo.Producto' with unique index 'UX_Producto_NombreClave'. The duplicate key value is ().

The statement has been terminated.

La causa del error se debe esencialmente a que el tipo de índice creado no permite la inserción de múltiples valores no conocidos NULL.

Para resolver esta limitación, SQL Server cuenta con la función de creación de índices filtrados; esto es, la especificación de una condición para un subconjunto determinados valores del dominio de un tipo de dato (Brimhall et al, 2015).

Proceso de la solución:

Eliminación del índice creado anteriormente:

DROP INDEX Producto.UX_Producto_NombreClave;

Creación del nuevo índice único filtrado:

CREATE UNIQUE INDEX UX_Producto_NombreClave ON Producto(NombreClave) WHERE NombreClave IS NOT NULL;

Nótese la especificación del filtro a través de WHERE NombreClave IS NOT NULL.: con esto se está indiciado que el campo NombreClave solo debe conservar la unicidad sobre valores distintos a NULL.

A continuación se han de insertar otros registros

INSERT INTO Producto (IdProducto, NombreProducto, NombreClave)
VALUES (4, 'Producto #4', NULL);

INSERT INTO Producto (IdProducto, NombreProducto, NombreClave)
VALUES (5, 'Producto #5', NULL);

Ahora ya es permitido la inserción de múltiples valores NULL:

(1 row(s) affected)

(1 row(s) affected)

Contenido de la tabla Producto:
Contenido de la tabla Producto
Figura 1. Contenido de la tabla Producto.

7. Conclusiones

Se ha demostrado cómo a través de un índice único filtrado es posible establecer una condición sobre la unicidad para los valores de una columna o varias columnas que pertenezcan al índice. En otras palabras: este tipo de operación es de inmensa utilidad para el programador de bases de datos, pues le permitirá aplicar una condición de unicidad para un subconjunto de datos que pertenezcan a un índice único. La próxima receta T-SQL explica cómo forzar la integridad referencial sobre columnas que permiten valores NULL.

8. Literatura & Enlaces

Brimhall, J., Dye, D., Gennick, J., Roberts, A., Sheffield, W. (2012). SQL Server 2012 T-SQL Recipes - A Problem-Solucion Approach. United States: Apress.
Create Unique Indexes (2015, diciembre 4). Recuperado desde: https://msdn.microsoft.com/en-us/library/ms187019.aspx.
Create Nonclustered Indexes (2015, diciembre 4). Recuperado desde: https://msdn.microsoft.com/en-us/library/ms189280.aspx.


V