Obtenga los registros del mes pasado en SQL server
Quiero obtener los registros del mes pasado basados en mi campo [miembro] de la tabla de la base de datos "date_created".
¿Cuál es el sql para hacer esto?
Para aclaración, último mes-1/8/2009 a 31/8/2009
Si hoy es 3/1/2010, necesitaré obtener los registros del 1/12/2009 al 31/12/2009.
17 answers
SELECT *
FROM Member
WHERE DATEPART(m, date_created) = DATEPART(m, DATEADD(m, -1, getdate()))
AND DATEPART(yyyy, date_created) = DATEPART(yyyy, DATEADD(m, -1, getdate()))
Es necesario comprobar el mes y el año.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-09 23:56:49
Todas las respuestas existentes (en funcionamiento) tienen uno de dos problemas:
- Ignorarán los índices en la columna que se está buscando
- La voluntad (potencialmente) seleccionar los datos que no se pretende, en silencio corromper sus resultados.
1. Índices ignorados:
En su mayor parte, cuando una columna que se busca tiene una función llamada a ella (incluso implícitamente, como para CAST
), el optimizador debe ignorar los índices en la columna y buscar a través de cada registro. He aquí un ejemplo rápido:
Estamos tratando con marcas de tiempo, y la mayoría de los RDBMSs tienden a almacenar esta información como un valor creciente de algún tipo, generalmente un long
o BIGINTEGER
recuento de mili-/nanosegundos. El tiempo actual se ve/se almacena así:
1402401635000000 -- 2014-06-10 12:00:35.000000 GMT
No ves el valor 'Year' ('2014'
) ahí, ¿verdad? De hecho, hay un poco de matemáticas complicadas para traducir hacia adelante y hacia atrás. Así que si llama a cualquiera de las funciones de la parte extracción / fecha en el buscado columna, el servidor tiene que realizar todas esas matemáticas solo para averiguar si puede incluirlo en los resultados. En tablas pequeñas esto no es un problema, pero a medida que el porcentaje de filas seleccionadas disminuye, esto se convierte en un drenaje cada vez más grande. Entonces, en este caso, lo estás haciendo por segunda vez para preguntar sobre MONTH
... bueno, te haces una idea.
2. Datos no deseados:
Dependiendo de la versión particular de SQL Server, y los tipos de datos de columna, usando BETWEEN
(o similar rangos de límite superior inclusivos: <=
) puede resultar en la selección de datos incorrectos . Esencialmente, puede terminar incluyendo datos de la medianoche del día "siguiente", o excluyendo alguna parte de los registros del día "actual".
Lo que tú deberías estar haciendo:
Así que necesitamos una forma que sea segura para nuestros datos, y usaremos índices (si es viable). El camino correcto es entonces de la forma:
WHERE date_created >= @startOfPreviousMonth AND date_created < @startOfCurrentMonth
Dado que solo hay un mes, @startOfPreviousMonth
puede ser fácilmente sustituida por / derivada por:
DATEADD(month, -1, @startOCurrentfMonth)
Si necesita derivar el inicio del mes actual en el servidor, puede hacerlo a través de lo siguiente:
DATEADD(month, DATEDIFF(month, 0, CURRENT_TIMESTAMP), 0)
Una breve explicación aquí. La inicial DATEDIFF(...)
obtendrá la diferencia entre el inicio de la era actual (0001-01-01
- AD, CE, lo que sea), esencialmente devolviendo un entero grande. Este es el conteo de meses hasta el inicio del mes actual . A continuación, añadimos este número al inicio de la era, que es en el inicio del mes.
Así que su script completo podría / debería ser similar a lo siguiente:
DECLARE @startOfCurrentMonth DATETIME
SET @startOfCurrentMonth = DATEADD(month, DATEDIFF(month, 0, CURRENT_TIMESTAMP), 0)
SELECT *
FROM Member
WHERE date_created >= DATEADD(month, -1, @startOfCurrentMonth) -- this was originally misspelled
AND date_created < @startOfCurrentMonth
Por lo tanto, todas las operaciones de fecha solo se realizan una vez, en un valor; el optimizador es libre de usar índices, y no se incluirán datos incorrectos.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-17 21:59:54
Agregue las opciones que se han proporcionado hasta ahora no usarán sus índices en absoluto.
Algo como esto hará el truco, y hará uso de un índice en la tabla (si existe).
DECLARE @StartDate DATETIME, @EndDate DATETIME
SET @StartDate = dateadd(mm, -1, getdate())
SET @StartDate = dateadd(dd, datepart(dd, getdate())*-1, @StartDate)
SET @EndDate = dateadd(mm, 1, @StartDate)
SELECT *
FROM Member
WHERE date_created BETWEEN @StartDate AND @EndDate
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-05 19:19:32
DECLARE @StartDate DATETIME, @EndDate DATETIME
SET @StartDate = DATEADD(mm, DATEDIFF(mm,0,getdate())-1, 0)
SET @EndDate = DATEADD(mm, 1, @StartDate)
SELECT *
FROM Member
WHERE date_created BETWEEN @StartDate AND @EndDate
Una actualización a la solución de mrdenny, de esta manera obtendrá exactamente el mes pasado desde YYYY-MM-01
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-20 07:45:21
Una forma de hacerlo es usando la función DATEPART :
select field1, field2, fieldN from TABLE where DATEPART(month, date_created) = 4
and DATEPART(year, date_created) = 2009
Devolverá todas las fechas en abril. Para el mes pasado (es decir, anterior al mes actual) puede usar GETDATE y DATEADD también:
select field1, field2, fieldN from TABLE where DATEPART(month, date_created)
= (DATEPART(month, GETDATE()) - 1) and
DATEPART(year, date_created) = DATEPART(year, DATEADD(m, -1, GETDATE()))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-15 03:50:06
El último mes considere como hasta el último día del mes. 31/01/2016 aquí el último día del mes sería el 31 de enero. que no es similar a los últimos 30 días.
SELECT CONVERT(DATE, DATEADD(DAY,-DAY(GETDATE()),GETDATE()))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-12 12:20:58
select * from [member] where DatePart("m", date_created) = DatePart("m", DateAdd("m", -1, getdate())) AND DatePart("yyyy", date_created) = DatePart("yyyy", DateAdd("m", -1, getdate()))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-15 03:48:03
DECLARE @StartDate DATETIME, @EndDate DATETIME
SET @StartDate = DATEADD(mm, DATEDIFF(mm, 0, getdate()) - 1, 0)
SET @EndDate = dateadd(dd, -1, DATEADD(mm, 1, @StartDate))
SELECT * FROM Member WHERE date_created BETWEEN @StartDate AND @EndDate
Y otra actualización a la solución de mrdenny.
También da el último día exacto del mes anterior.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-19 21:56:17
declare @PrevMonth as nvarchar(256)
SELECT @PrevMonth = DateName( month,DATEADD(mm, DATEDIFF(mm, 0, getdate()) - 1, 0)) +
'-' + substring(DateName( Year, getDate() ) ,3,4)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-15 22:18:24
Consulta SQL para obtener solo el registro del mes actual
SELECT * FROM CUSTOMER
WHERE MONTH(DATE) = MONTH(CURRENT_TIMESTAMP) AND YEAR(DATE) = YEAR(CURRENT_TIMESTAMP);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-11 18:21:20
En Sql server para el último mes:
select * from tablename
where order_date > DateAdd(WEEK, -1, GETDATE()+1) and order_date<=GETDATE()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-06 15:02:11
DECLARE @curDate INT = datepart( Month,GETDATE())
IF (@curDate = 1)
BEGIN
select * from Featured_Deal
where datepart( Month,Created_Date)=12 AND datepart(Year,Created_Date) = (datepart(Year,GETDATE())-1)
END
ELSE
BEGIN
select * from Featured_Deal
where datepart( Month,Created_Date)=(datepart( Month,GETDATE())-1) AND datepart(Year,Created_Date) = datepart(Year,GETDATE())
END
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-01 10:54:31
DECLARE @StartDate DATETIME, @EndDate DATETIME
SET @StartDate = dateadd(mm, -1, getdate())
SET @StartDate = dateadd(dd, datepart(dd, getdate())*-1, @StartDate)
SET @EndDate = dateadd(mm, 1, @StartDate)
set @StartDate = DATEADD(dd, 1 , @StartDate)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-15 15:08:37
WHERE
date_created >= DATEADD(MONTH, DATEDIFF(MONTH, 31, CURRENT_TIMESTAMP), 0)
AND date_created < DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-01 01:06:28
Soy de Oracle env y lo haría así en Oracle:
select * from table
where trunc(somedatefield, 'MONTH') =
trunc(sysdate -INTERVAL '0-1' YEAR TO MONTH, 'MONTH')
Idea: Estoy ejecutando un informe programado del mes anterior (desde el día 1 hasta el último día del mes, no con ventana). Esto podría ser un índice hostil, pero Oracle tiene un manejo rápido de la fecha de todos modos. ¿Existe una forma similar simple y corta en MS SQL? La respuesta que compara el año y el mes por separado parece tonta para la gente de Oracle.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-15 07:49:44
Puede obtener los registros del último mes con esta consulta
SELECT * FROM dbo.member d
WHERE CONVERT(DATE, date_created,101)>=CONVERT(DATE,DATEADD(m, datediff(m, 0, current_timestamp)-1, 0))
and CONVERT(DATE, date_created,101) < CONVERT(DATE, DATEADD(m, datediff(m, 0, current_timestamp)-1, 0),101)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-27 14:56:44
La forma en que solucioné un problema similar fue agregando Mes a mi SELECCIONAR porción
Month DATEADD(day,Created_Date,'1971/12/31') As Month
Y que he añadido DONDE declaración
Month DATEADD(day,Created_Date,'1971/12/31') = month(getdate())-1
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-30 09:38:13