2009-07-11 24 views
6

Estoy tratando de enumerar las últimas estadísticas de un sitio web. Incluí los últimos 30 días con;GETDATE el mes pasado

CONVERT(VARCHAR(10), S.DATEENTERED, 101) 
    BETWEEN 
    CONVERT(VARCHAR(10), GETDATE()-30, 101) 
    AND 
    CONVERT(VARCHAR(10), GETDATE(), 101) 

y este mes con;

RIGHT(CONVERT(VARCHAR(10), S.DATEENTERED, 103), 7) = 
RIGHT(CONVERT(VARCHAR(10), GETDATE(), 103), 7) 

pero no tengo idea de qué consulta usar el mes pasado. Lo intenté con;

RIGHT(CONVERT(VARCHAR(10), S.DATEENTERED, 103), 7) = 
RIGHT(CONVERT(VARCHAR(10), GETDATE()-1, 103), 7) 

No funcionó.

Respuesta

11

A continuación se encuentra el inicio del último mes:

-- Start of last month 
SELECT CAST('01 '+ RIGHT(CONVERT(CHAR(11),DATEADD(MONTH,-1,GETDATE()),113),8) AS datetime) 

A continuación, encontrar el principio de este mes, usando el siguiente, menos uno.

-- Start of the month 
SELECT CAST('01 '+ RIGHT(CONVERT(CHAR(11),GETDATE(),113),8) AS datetime) 

Cuando tengo que trabajar con fechas en SQL Server que a menudo hacen referencia a Robyn Page's SQL Server DATE/TIME Workbench. El banco de trabajo (tutorial) está bien diseñado y contiene casi todo lo que alguna vez necesité al trabajar con fechas en SQL Server.

2

Intente utilizar la función DATEADD. Puede agregar un -1 con la fecha de MES (mm) y debería funcionar. Here is a link

1
where year(S.DATEENTERED) = year(dateadd(mm, -1, getdate())) and month(S.DATEENTERED) = month(dateadd(mm, -1, getdate())) 

no puede ser bueno en cuanto al rendimiento, sino que tienes la idea.

0

Probar:

declare @lastm int 
set @lastm = datepart(mm,getdate()) - 1 

...

where datepart(mm,s.dateentered) = @lastm 
+0

Piensa qué pasará si el mes pasado belogs para el año pasado. – GSerg

0

conseguir el primer día del último mes

SELECT DATEADD(MM, DATEDIFF(MM, '01/01/2000', DATEADD(MM, -1,GETDATE())), '01/01/2000') 

acceder al último día del último mes

SELECT DATEADD(SS,-1,DATEADD(MM, DATEDIFF(MM,'01/01/2000',GETDATE()),'01/01/2000')) 

Luego busque basado en este rango.

15

Las fechas siempre son un placer para trabajar en cualquier lenguaje de programación, SQL no se excluye.

Para responder a su pregunta para encontrar todos los registros que se produjeron el mes pasado

select S.DATEENTERED 
     ,* 
    from sometable S 
where S.DATEENTERED 
     between dateadd(mm, datediff(mm, 0, dateadd(MM, -1, getdate())), 0) 
      and dateadd(ms, -3, dateadd(mm, datediff(mm, 0, dateadd(MM, -1, getdate())) + 1, 0)) 
order by 1 

Para expandir el mejor medio para conseguir los registros dentro de un determinado plazo de tiempo es mediante la utilización de la función DateDiff, la función dateadd, y el entre condición en la cláusula where.

select 'howdy' 
     ,getdate() 
where getdate() 
     between dateadd(mm, 0, 0) 
      and dateadd(ms, -3, dateadd(mm, datediff(mm, 0, dateadd(mm,-1,getutcdate())) + 1, 0)) 

El código anterior resultará en ningún registro devuelto, ya que es la comprobación para ver si la fecha de hoy es entre 1900-01-01 00: 00: 00.000 y la última fecha de grabación posible del mes pasado (el último día y 23: 59: 59.997 - Las columnas DATETIME de SQL Server tienen como máximo una resolución de 3 milisegundos).

El siguiente código arrojará un registro ya que la fecha que estamos buscando es hace un mes.

select 'howdy' 
     ,dateadd(mm, -1, getdate()) 
where dateadd(mm, -1, getdate()) 
     between dateadd(mm, 0, 0) 
      and dateadd(ms, -3, dateadd(mm, datediff(mm, 0, dateadd(mm,-1,getutcdate())) + 1, 0)) 

un desglose de la cláusula where:

WHERE getdate() -- date to check 
between dateadd(mm, 0, 0) -- begin date 
and dateadd(ms, -3, dateadd(mm, datediff(mm, 0, dateadd(mm,-1,getutcdate())) + 1, 0)) -- end date 

Por último, una variedad de fechas se puede determinar de esta manera aquí es una lista bastante completa:

select dateadd(mm, 0, 0) as BeginningOfTime 
     ,dateadd(dd, datediff(dd, 0, getdate()), 0) as Today 
     ,dateadd(wk, datediff(wk, 0, getdate()), 0) as ThisWeekStart 
     ,dateadd(mm, datediff(mm, 0, getdate()), 0) as ThisMonthStart 
     ,dateadd(qq, datediff(qq, 0, getdate()), 0) as ThisQuarterStart 
     ,dateadd(yy, datediff(yy, 0, getdate()), 0) as ThisYearStart 
     ,dateadd(dd, datediff(dd, 0, getdate()) + 1, 0) as Tomorrow 
     ,dateadd(wk, datediff(wk, 0, getdate()) + 1, 0) as NextWeekStart 
     ,dateadd(mm, datediff(mm, 0, getdate()) + 1, 0) as NextMonthStart 
     ,dateadd(qq, datediff(qq, 0, getdate()) + 1, 0) as NextQuarterStart 
     ,dateadd(yy, datediff(yy, 0, getdate()) + 1, 0) as NextYearStart 
     ,dateadd(ms, -3, dateadd(dd, datediff(dd, 0, getdate()) + 1, 0)) as TodayEnd 
     ,dateadd(ms, -3, dateadd(wk, datediff(wk, 0, getdate()) + 1, 0)) as ThisWeekEnd 
     ,dateadd(ms, -3, dateadd(mm, datediff(mm, 0, getdate()) + 1, 0)) as ThisMonthEnd 
     ,dateadd(ms, -3, dateadd(qq, datediff(qq, 0, getdate()) + 1, 0)) as ThisQuarterEnd 
     ,dateadd(ms, -3, dateadd(yy, datediff(yy, 0, getdate()) + 1, 0)) as ThisYearEnd 

Utilizando el lista anterior se puede determinar un rango de cualquier tipo.

+0

"Las columnas SQL Server DATETIME tienen una resolución de 3 milisegundos como máximo" es un hecho poco conocido. Solo he oído mencionar esta gema una vez. Gran detalle. –

+0

+1 a ahsteele para obtener detalles y una solución muy aceptable. –

4

Sugiero utilizar el primer día del mes pasado y el primer día del mes actual para la operación y en lugar de usar BETWEEN use> = y <. Esa es mi opinión personal, pero creo que habrá beneficios de rendimiento y mantenimiento para este enfoque.

Aquí está el sql. Notarás que he incluido el último día del valor del último mes en caso de que termines con otro enfoque.

Tenga en cuenta que estas fechas se basan fuera de las 12:00 AM de ese día. En otras palabras, obtener los valores entre 01/06/2009 y 30/06/2009 no le proporcionará lo que desea, ya que se excluyó todo el 30/06/2009. Si usa el primer día de julio (1 de julio de 2009), tiene cobertura.

De nuevo, recomiendo evitar ENTRE todos juntos como se muestra a continuación. La mejor de las suertes.

Declare @LastMonthFirstDay datetime 
Declare @LastMonthLastDay datetime 
Declare @ThisMonthFirstDay datetime 

Set @LastMonthFirstDay = DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP) - 1, 0); 
Set @ThisMonthFirstDay = DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0); 
Set @LastMonthLastDay = DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0)); 

Select * From Table 
Where DateEntered >= @LastMonthFirstDay 
And DateEntered < @ThisMonthFirstDay; 
+0

Creo que su enfoque de asignar las fechas límite a las variables es ciertamente más fácil de mantener. Sin embargo, tenía la impresión de que BETWEEN tenía un mejor rendimiento que el de un constructo> = <. – ahsteele

+0

@ahsteele - Puede que tengas razón. Como mencionaste, "las fechas son un placer trabajar con ellas". Descubrí que necesitaba modificar mis consultas, al filtrar las fechas, varias veces antes de lograr que funcionen lo mejor posible. Descubrí que> = con

6

¿Qué tal esto?

select DATEADD(month, -1, GETDATE()) 
+0

excelente. +1 para la consulta más corta – BNN

Cuestiones relacionadas