Cálculo y funciones relacionadas a Fechas.

Crear indices faltantes

Como buscar y crear índices faltantes en nuestra base de datos

Navegando por la web me tope con esta conjunto de scripts recomendado por Microsoft que aseguran ser útil para cualquier DBA

https://gallery.technet.microsoft.com/Some-random-collection-of-b607bf1b

Como siempre son para MS SQL Server.

Entre ellos encontré uno muy útil que analiza las estadísticas de una base en producción y trate de generarte el TSQL para crear los índices recomendados faltantes

Veamos el código

/**********************************************
--Missing Index Script
**********************************************/

SELECT TOP 25
dm_mid.database_id AS DatabaseID,
dm_migs.avg_user_impact*(dm_migs.user_seeks+dm_migs.user_scans) Avg_Estimated_Impact,
dm_migs.last_user_seek AS Last_User_Seek,
OBJECT_NAME(dm_mid.OBJECT_ID,dm_mid.database_id) AS [TableName],
'CREATE INDEX [IX_' + OBJECT_NAME(dm_mid.OBJECT_ID,dm_mid.database_id) + '_'
+ REPLACE(REPLACE(REPLACE(ISNULL(dm_mid.equality_columns,''),', ','_'),'[',''),']','') +
CASE
WHEN dm_mid.equality_columns IS NOT NULL AND dm_mid.inequality_columns IS NOT NULL THEN '_'
ELSE ''
END
+ REPLACE(REPLACE(REPLACE(ISNULL(dm_mid.inequality_columns,''),', ','_'),'[',''),']','')
+ ']'
+ ' ON ' + dm_mid.statement
+ ' (' + ISNULL (dm_mid.equality_columns,'')
+ CASE WHEN dm_mid.equality_columns IS NOT NULL AND dm_mid.inequality_columns IS NOT NULL THEN ',' ELSE
'' END
+ ISNULL (dm_mid.inequality_columns, '')
+ ')'
+ ISNULL (' INCLUDE (' + dm_mid.included_columns + ')', '') AS Create_Statement
FROM sys.dm_db_missing_index_groups dm_mig
INNER JOIN sys.dm_db_missing_index_group_stats dm_migs
ON dm_migs.group_handle = dm_mig.index_group_handle
INNER JOIN sys.dm_db_missing_index_details dm_mid
ON dm_mig.index_handle = dm_mid.index_handle
WHERE dm_mid.database_ID = DB_ID()
ORDER BY Avg_Estimated_Impact DESC
GO

Resultado de correr el script

Luego de unos segundos veremos algo de este estilo:

buscando indices faltantes con tsqlPodremos ver el tiempo promedio estimado de mejora al realizar el índice, como el TSQL para crearlo.

(*) Un error que tiene el script es el nombre del índice que genera, que no debe superar los 128 caracteres, y en el mismo no lo contempla.

Por lo demás promete cumplir lo que ofrece….

Actualmente lo estoy probando en mis bases de producción como alternativa a la herramienta de análisis de rendimiento de MS SQL Server

Obtener el ultimo día del mes con SQL Server

Como obtener el último día del mes con TSQL en SQL Server

Anteriormente habíamos visto como podíamos obtener:

Primer y último día de Mes Anterior, Actual y Siguiente.

Si te interesa ( y trabajas con una versión anterior a MS SQL Server 2012), les dejo el tutorial anterior:

https://maurobernal.com.ar/blog/t-sql/primer-y-ultimo-dia-del-mes-con-sql-server-y-otros/

Pero en esta oportunidad veremos otra variante para obtener el último día del mes: actual, mes anterior y mes siguiente.

Usando la funtión EOMONTH()

A partir de Microsoft SQL Server 2012 se agregó la función EOMONTH()

https://docs.microsoft.com/en-us/sql/t-sql/functions/eomonth-transact-sql

La misma permite obtener el último día del mes

Veamos un ejemplo:

--GetDate() -> 14 Nov 2017

--Último día del mes Actual
select EOMONTH(getdate()) as UltDiaMesActual

--Último día del mes Anterior
select EOMONTH(getdate(),-1) as UltDiaMesAnterior

--Último día del mes Próximo
select EOMONTH(getdate(),1) as UltDiaMesProximo

Esto nos dará como resultado:

usando_eomonth_ejemploCon un poco de ingenio podemos obtener un poco más

A partir del código anterior, con un poco de ingenio, y con ayuda de la función DateAdd()

https://docs.microsoft.com/en-us/sql/t-sql/functions/dateadd-transact-sql

Si le agregamos un día podemos obtener el primer día del mes anterior, mes actual y mes próximo

--GetDate() -> 14 Nov 2017

--Primer día del Mes Anterior
select dateadd(d,1,EOMONTH(getdate(),-2)) as PrimerDiaMesAnterior

--Primer día del Mes Actual
select dateadd(d,1,EOMONTH(getdate(),-1)) as PrimerDiaMesActual

--Primer Dia del Mes Siguiente
select dateadd(d,1,EOMONTH(getdate())) as PrimerDiaMesSiguiente

El resultado sería el siguiente:

eomoth para primer dia del mes

 

No se olviden de comentar si les sirvió, !!! Y cualquier cosa que necesiten hacer es posible con un poco de paciencia…

Contar días hábiles entre una fecha

Como contar días entre fechas

La siguiente función para SQL Server permite contar la cantidad de días que existen entre un rango de fechas sin contar Sábados y Domingos.

CREATE FUNCTION [dbo].[DiasHabiles](@FechaInicio DATETIME,@FechaFin DATETIME) 
 RETURNS integer 
 AS 
 BEGIN

            DECLARE @DiasNormales INT	--Con esta variable calculamos cuantos dias "normales" hay en el rango de fechas 
            DECLARE @DiasHabiles INT  --Con esta variable acumulamos los dias totales 
            DECLARE @Contador INT		--Esta variable nos sirve de contador para saber cuando lleguemos al ultimo dia del rango 
            DECLARE @Aux_Fecha DATETIME	--Esta variable es la que comparamos para saber si el dia que esta calculando es sábado o domingo*

            /*Esta par de variables sirven para comparar las dos fechas, si son iguales, la funcion nos regresa un 0*/ 
            DECLARE @Aux_FechaInicio VARCHAR(10) 
            DECLARE @Aux_FechaFin VARCHAR(10) 

            --Inicializamos algunas variables 

			SET @DiasNormales = 0 
            SET @DiasHabiles = 0 
            SET @Contador=0 

            --Calculamos cuantos dias normales hay en el rango de fechas  
            SELECT @DiasNormales = DATEDIFF(DAY,@FechaInicio,@FechaFin) + 1 

            /*Ordenamos el formato de las fechas para que no importando como se proporcionen se comparen igual*/ 

            SELECT @Aux_FechaInicio = (SELECT CAST((CAST(datepart(dd,@FechaInicio)AS 
                                   VARCHAR(2))+'/'+ CAST(datepart(mm,@FechaInicio)AS 
                                   VARCHAR(2))+'/'+CAST(datepart(yy,@FechaInicio)AS VARCHAR(4))) as 
                                   varchar(10))) 
            SELECT @Aux_FechaFin = (SELECT CAST((CAST(datepart(dd,@FechaFin)AS 
                                   VARCHAR(2))+'/'+ CAST(datepart(mm,@FechaFin)AS VARCHAR(2))+'/'+ 
                                   CAST(datepart(yy,@FechaFin)AS VARCHAR(4)))as varchar(10))) 


            --Se comparan las dos fechas 

            IF @Aux_FechaInicio <>@Aux_FechaFin 
			BEGIN 
				/*Si la diferencia de fechas es igual a dos, es porque solo ha transcurrido un dia, asi que solo se valida que no vaya a marcar dias de mas*/ 
				IF @DiasNormales = 2 
				BEGIN 
					SELECT @DiasHabiles = 1 
				END 
				ELSE 
				BEGIN 
					WHILE @Contador < @DiasNormales 
					BEGIN 
						/*Se Iguala la fecha a que vamos a calcular para saber si es sabado o domingo en la variable @Aux_Fecha sumandole los dias que marque el contador, el cual no debe ser mayor que el numero total de dias que hay en el rango de fechas*/ 
						SELECT @Aux_Fecha = @FechaInicio + @Contador 
						/*Utilizando la funcion datepart con el parametro dw que calcula que dia de la semana corresponde una fecha determinada, determinados que no sea sabado (7) o domingo (1)*/ 
							IF ((datepart(dw,@Aux_Fecha) <> 1) and (datepart(dw,@Aux_Fecha) <> 7) ) 
							BEGIN
								/*Si no es sabado o domingo, entonces se suma uno al total de dias que queremos desplegar*/ 
								SELECT @DiasHabiles = @DiasHabiles + 1 
							END 
						--Se suma un dia mas al contador 
						SELECT @Contador = @Contador + 1 
					END 
				END 
			END 
            ELSE 
            BEGIN 
            --Si fuese cierto que las fechas eran iguales se despliegue cero 
            SELECT @DiasHabiles = 0 
            END 

            --Al finalizar el ciclo, la funcion regresa el numero total de dias 
            RETURN(@DiasHabiles) 
END

GO

 

Su uso es muy simple:

Select dbo.DiasHabiles('2015/07/13','2015/07/31') as DiasHabiles,DateDiff(d,'2015/07/13','2015/07/31') as DiasCorridos

 

 

Resultado_contar_fechas

En este ejemplo se puede ver la variación que existe entre la función DateDiff y nuestra función.

Quitar microsegundos a una fecha en SQL Server

De la siguiente manera podrán quitar (truncar) la fechas para quitarles los microsegundos.

–Como Quedaria sin los microsegundos

SELECT
CampoFecha
,DATEADD(MILLISECOND,
DATEPART(MILLISECOND ,
CampoFecha

)
,
CampoFecha

)
as Resultado From Tabla

 

–Update de la Tabla

update Tabla set
CampoFecha=DATEADD(MILLISECOND,
DATEPART(MILLISECOND ,
CampoFecha

)
,
CampoFecha

)


 

Ultimo dia del Mes con SQL Server y otros

Trabajando con funciones TSQL para realizar cálculos de Fechas

A continuación una serie de funciones en TSQL útiles para el cálculo de fechas:

-->Mes Actual:
-----------------------------------
--Primer día del mes actual
SELECT DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0))
--Último día del mes actual
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))

-->Mes Anterior:
-----------------------------------
--Primer día del mes anterior
SELECT DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0,GETDATE())-1,0))
--Último día del mes anterior
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0))

-->Mes Siguiente:
-----------------------------------
----Primer día del mes siguiente
SELECT DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))
----Último día del mes siguiente
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+2,0))


--> Trimestre Actual:
-----------------------------------
----Primer día del trimestre actual
SELECT DATEADD(qq,DATEDIFF(qq,0,GETDATE()),0) 
----Último día del trimestre actual
SELECT DATEADD(qq,DATEDIFF(qq,-1,GETDATE()),-1)

Resultados

Con la fecha 10 de Noviembre del 2017 esto serían los resultados

Primer_Y_Ultimo_Dia_Resultados

 

Otra alternativa

Continuando con el trabajo con fechas con TSQL podemos hacer lo mismo, pero con una función nativa: EOMONTH()

Si les interesa les dejo el link, que incluye como siempre un caso práctico:


Obtener el número de la Semana

Una función muy simple en diferentes lenguajes para obtener el número de la semana.

Obtener el número de semana del año con PERL

my $numeroSemana = POSIX::strftime("%V", gmtime time);

Obtener el número de semana del año con PHP

$numeroSemana = date("W"); 

o date(“W”, epoch). Se usa la letra mayúscula ‘W’.

Obtener el número de semana del año con SQL

En MySQL:

 SELECT WEEKOFYEAR(NOW())

 o

 SELECT WEEK(NOW(),3)

 

En MS SQL Server:

SELECT DATEPART( wk, GETDATE() )