En este post vamos a aprender a obtener la edad de los usuarios que tenemos registrado en nuestra base de datos y también determinar cuántos de ellos son mayores de edad y cuantos son menores de edad , para esto vamos utilizar la función DATEDIFF.
Esta función lo que hace es calcular el intervalo de tiempo entre dos fechas dependiendo del primer argumento que puede ser day, month, year el es un entero que depende de la diferencia entre los dos argumentos Fecha2-Fecha1.
Para nuestro ejemplo vamos a tener una tabla con el nombre Usuario que tendrá estos datos.
Id es autoincrementa, Nombre un varchar(150), Sexo char(1) y FechaNac es un datetime.
La query muestra el campo Nombre, Sexo y Edad, edad se obtiene de la diferencia entre el campo FechaNac y la fecha actual.
SELECT Nombre
,Sexo
,DATEDIFF(YEAR, FechaNac, GETDATE()) AS Edad
FROM Usuario
Ahora tenemos la edad de cada uno de los usuarios, con estos nuevos datos podemos determinar quien es mayor de edad y quien es menor de edad, para esto vamos a utilizar la función CASE que lo que hace es comparar dos o más valores y devolver un resultado, por cada valor hay un WHEN y THEN, si hay una coincidencia ejecuta el THEN por el contrario ejecuta el ELSE pero si no ponemos el ELSE devuelve NULL para finalizar el CASE ponemos END.
En la query vamos a mostrar el Nombre, Sexo y Edad a esto agregamos dos columnas una "Menor" y otra "Mayor" si la edad es mayor a 18 años entonces en la columna que corresponde vamos a poner un 1 de lo contrario un 0, para los menores de edad hacemos lo mismo.
SELECT Nombre
,Sexo
,DATEDIFF(YEAR, FechaNac, GETDATE()) AS Edad
,CASE WHENDATEDIFF(YEAR, FechaNac, GETDATE()) < 18
THEN 1 ELSE 0 END AS Menor
,CASE WHENDATEDIFF(YEAR, FechaNac, GETDATE()) >= 18
THEN 1 ELSE 0 END AS Mayor
FROM Usuario
Y para finalizar vamos a utilizar la función SUM para sumar y obtener como resultado la cantidad de mayores y menores.
SELECT SUM(CASE WHENDATEDIFF(YEAR, FechaNac, GETDATE()) < 18
THEN 1 ELSE 0 END) AS Menor
,SUM(CASE WHENDATEDIFF(YEAR, FechaNac, GETDATE()) >= 18
THEN 1 ELSE 0 END) AS Mayor
FROM Usuario
Highcharts es la librería que más utilizo para realizar gráficos en mis aplicaciones web, principalmente por la variedad de tipos de gráficos, compatibilidad con los navegadores, es gratuito, tiene muchos ejemplos y sobre todo por lo sencillo que es.
Esta escrita en JavaScrip lenguaje que todo programador hoy por hoy tiene que dominar.
En la página oficial de Highcharts hay mucha documentación es importante que le den un a mirada.
Ejemplo de Highcharts - Line
La idea principal es mostrar la cantidad de usuarios que se registraron en una fecha determinada por cada ciudad.
Para el ejemplo vamos a trabajar con Visual Studio 2013 y Sql Server en cualquier versión.
Antes de nada debemos tener listo
JQuery porque el framework (Highcharts) depende de él.
Descar highcharts.js de la página Highcharts ir a la opción Support -> Donwload hoy están en la versión 6.2.
En ambos casos si no queremos descargar las librerias podemos usar el CDN
En Sql Server hay que crear una base de datos con el nombre Highcharts y dentro de ella nuestras tablas.
Tabla Ciudad
El campo Id es un entero autoincremental y la Descripcion es un varchar(150)
Tabla Usuarios
Id es un entero autoincremental, Nombre es un varchar(150), Fecha es Datetime y Ciudad_id es un foreign key de la tabla Ciudad.
Stored Procedure
La query obtiene los datos para ser visualizado en el gráfico.
CREATE PROCEDURE CantidadRegistros_PorCiudad
AS
BEGINDECLARE @Fecha_Reg TABLE ( Fecha DATETIME )
INSERT INTO @Fecha_Reg
SELECTDISTINCT(CONVERT(VARCHAR(10), Fecha, 103))
FROM Usuarios
SELECT CONVERT(VARCHAR(10), U.Fecha, 103) AS 'Fecha'
,'Santa Cruz' = SUM(CASE WHEN U.Ciudad_id = 3 THEN 1
ELSE 0 END)
,'LaPaz' = SUM(CASE WHEN U.Ciudad_id = 2 THEN 1
ELSE 0 END)
,'Cochabamba' = SUM(CASE WHEN U.Ciudad_id = 1 THEN 1
ELSE 0 END)
FROM Usuarios U
WHERE CONVERT(VARCHAR(10), U.Fecha, 103) IN (SELECT Fecha
FROM @Fecha_Reg )
GROUP BYCONVERT(VARCHAR(10), U.Fecha, 103)
END
Creación del proyecto.
Una vez creado nuestro proyecto vamos al Web.config y ubicamos <connectionStrings /> aquí debemos configurar nuestra cadena de conexión.
Para el acceso a los datos vamos a crear una clase que se llame Ado.
Esta clase genérica la utilizo cada vez que voy acceder a la base de datos. El método Retrieve devuelve un DataTable y recibe como parámetro el nombre del stored a ejecutar.
La clase datos va tener un solo método getDatos y le vamos a decir que ejecute el stored que tenemos arriba CantidadRegistros_PorCiudad.
public class Datos
{
Ado ado;
public Datos()
{
ado = newAdo();
}
public DataTable getDatos()
{
return ado.Retrieve("CantidadRegistros_PorCiudad");
}
}
Creo que hasta aquí todo va bien, ya tenemos casi todo listo para empezar a pensar en crear otras clases que nos permitan cumplir con nuestro objetivo.
Debemos crear otra clase con el nombre SeriesItem, el primer atributo es un string que almacenará el nombre de la Ciudad y el segundo atributo es un vector de enteros, más adelante veremos lo importante de este atributo.
public class SeriesItem
{
publicstring name { get; set; }
public int[] data { get; set; }
}
También vamos a crear la clase LineaCharts al igual que la anterior clase tiene dos atributos el primero es una lista de SeriesItem y el segundo es un vector de string, en este vector almacenaremos las fechas de registro de los usuarios, si le dan una mirada al stored las fechas son únicas porque en una misma fecha se pueden registrar más de un usuario.
public class LineaCharts
{
publicList<SeriesItem> series { get; set; }
publicstring[] fechas { get; set; }
public LineaCharts(List<SeriesItem> iSeries, string[] iFechas)
{
series = iSeries;
fechas = iFechas;
}
}
Por último vamos a crear un item de tipo Web Form al que pondremos de nombre GraficarLineaChart.
En el CodeBehind escribimos este código, no olvidar la linea using System.Web.Services; de lo contrario no va salir error en el [WebMethod].
Mediante ajax se hace una llamada asíncrona al método CantidadRegistros_PorCiudad el cual devuelve un objeto de tipo LineaCharts.
El método getDato devuelve los datos obtenidos de la base de datos, almacenamos en un DateTable.
public partial class GraficarLineaChart : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
[WebMethod]
public static LineaCharts CantidadRegistros_PorCiudad()
{
DataTable dt = newDatos().getDatos();
if (dt != null && dt.Rows.Count > 0)
{
List<SeriesItem> series = newList<SeriesItem>();
string[] fechas = new string[dt.Rows.Count];
int[] sc = new int[dt.Rows.Count];
int[] lp = new int[dt.Rows.Count];
int[] cb = new int[dt.Rows.Count];
int i = 0;
foreach (DataRow dr in dt.Rows)
{
fechas[i] = dr[0].ToString();
sc[i] = Convert.ToInt32(dr[1].ToString());
lp[i] = Convert.ToInt32(dr[2].ToString());
cb[i] = Convert.ToInt32(dr[3].ToString());
i++;
}
series.Add(newSeriesItem() { name = "Santa Cruz", data = sc });
series.Add(newSeriesItem() { name = "La Paz", data = lp });
series.Add(newSeriesItem() { name = "Cochabamba", data = cb });
return newLineaCharts(series, fechas);
}
else
{
return null;
}
}
}
Como vamos a hacer una llamada asíncrona mediante Ajax de JQuery esta tiene varias propiedades.
type: tipo de llamada que por defecto es GET.
url: ruta a la cual le vamos hacer el pedido.
data: datos que se envían al servidor, se envía un string con formato JSON.
contentType: tipo de datos que van a ser enviados al servidor.
dataType: tipo de dato que se espera recibir desde el servidor JQuery los interpreta con los MIMES types que el soporta. Los valores válidos son (xml, json. html, text, script, jsop).
En nuestro caso vamos hacer un POST, se ejecutará en nuestra misma página (le pasamos el nombre de nuestra página y el método), el tipo de dato es JSON.
Y por último vamos a generar el gráfico desde un botón btnCreatePieChart, en el script se muestra que está esperando un click de este botón para ejecutar el método GraficarDatos
En muchas ocaciones tenemos datos repetidos en nuestra tabla y es necesario eliminarlos. En este post vamos explicar cómo hacerlo, para esto tendremos la siguiente tabla a la que llamaremos Usuario.
Para nuestro ejemplo debemos tener estos registros, nótese que la columna Dni está remarcado con color rojo lo que indica que son los registros repetidos.
Como solo tenemos 13 registros pues nos resulta fácil determinar cuales son los repetidos, el problema es cuando tenemos muchos registros, entonces lo que tenemos que hacer es una query que nos muestre cuáles son los que se están repitiendo.
Algo rápido que podemos hacer es escribir una query que nos dé como resultado la cantidad de veces que están repetidos.
Como estamos haciendo uso de una función de agregado (COUNT) necesitamos agrupar por las columnas a mostrar, en este caso agrupamos por Nombre y Dni. Ahora ya sabemos la cantidad de veces que se repite un registro.
Necesitamos determinar cuáles son los registros que se repiten, para esto debemos hacer un Inner Join entre la misma tabla y devolver aquellos Id que están en ambas con la condición que el Id de la tabla Usuario A sea mayor al de la B.
SELECTA.IdFROMUsuario A INNER JOIN Usuario BONA.Nombre = B.Nombre
AND A.Dni = B.Dni
AND A.Id > B.Id
Ahora recién procedemos a eliminar los registros repetidos, ejecutamos esta query y verificamos los resultados.
DELETEUsuarioWHERE Id IN (SELECTA.IdFROMUsuario A INNER JOIN Usuario B ONA.Nombre = B.Nombre
AND A.Dni = B.Dni
AND A.Id > B.Id)
Select *
FROM Usuario