Получение записей за последний месяц в SQL server


Я хочу получить записи за последний месяц на основе моего поля db table [member]"date_created".

Что такое sql для этого?

для уточнения, последний месяц-с 1/8/2009 по 31/8/2009

Если сегодня 3/1/2010, мне нужно будет получить записи с 1/12/2009 по 31/12/2009.

17 52

17 ответов:

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()))

нужно проверить месяц и год.

все существующие (работа) ответы имеют одну из двух проблем:

  1. они будут игнорировать индексы в столбце при поиске
  2. воля (потенциально) выбирает данные, которые не предназначены, молча разрушая ваши результаты.

1. Игнорируемые Индексы:

по большей части, когда искомый столбец имеет функцию, вызываемую на нем (в том числе неявно, например, для CAST), оптимизатор должен игнорировать индексы на колонке и поиск по каждой записи. Вот краткий пример:

мы имеем дело с метками времени, и большинство РСУБД, как правило, хранят эту информацию в виде возрастающего значения какого-то типа, обычно a long или BIGINTEGER количество миллисекунд / наносекунд. Текущее время таким образом выглядит/хранится следующим образом:

1402401635000000  -- 2014-06-10 12:00:35.000000 GMT

вы не видите значение "год" ('2014') там, не так ли? На самом деле, есть довольно сложная математика для перевода туда и обратно. Так что если вы вызываете любую из функций извлечения / даты в столбце поиска, сервер должен выполнить всю эту математику, чтобы выяснить, можно ли включить ее в результаты. В небольших таблицах это не проблема, но по мере уменьшения процента выбранных строк это становится все большим и большим утечкой. Тогда в этом случае, вы делаете это во второй раз спрашиваю о MONTH... ну, вы поняли картину.

2. Непреднамеренные данные:

в зависимости от конкретная версия SQL Server и типы данных столбцов, используя BETWEEN (или аналогичные включительные диапазоны верхней границы:<=)может привести к неправильному выбору данных. По сути, вы потенциально можете включить данные с полуночи " следующего "дня или исключить некоторую часть записей" текущего " дня.

что ты должны делаем:

поэтому нам нужен способ, который безопасен для наших данных, и будет использовать индексы (если жизнеспособный.) Правильный путь тогда имеет вид:

WHERE date_created >= @startOfPreviousMonth AND date_created < @startOfCurrentMonth

учитывая, что есть только один месяц, @startOfPreviousMonth может быть легко заменен на/выведен:

DATEADD(month, -1, @startOCurrentfMonth)

Если вам нужно вывести начало текущего месяца на сервере, вы можете сделать это с помощью следующего:

DATEADD(month, DATEDIFF(month, 0, CURRENT_TIMESTAMP), 0)

краткое объяснение здесь. Начальная DATEDIFF(...) получит разницу между началом текущей эпохи (0001-01-01 - AD, CE, что угодно), по существу возвращая большой целое число. Это количество месяцев до начала настоящее месяц. Прибавим это число к началу эпохи, которая находится в начале данного месяца.

таким образом, ваш полный скрипт может / должен выглядеть следующим образом:

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

таким образом, все операции с датами выполняются только один раз, на одном значении; оптимизатор может свободно использовать индексы, и никакие неправильные данные не будут включены.

добавить параметры, которые были предоставлены до сих пор не будет использовать ваши индексы на всех.

что-то вроде этого будет делать трюк, и использовать индекс в таблице (если он существует).

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
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

обновление до решения mrdenny, таким образом, вы получите ровно в прошлом месяце от YYYY-MM-01

один из способов сделать это с помощью DATEPART функция:

select field1, field2, fieldN from TABLE where DATEPART(month, date_created) = 4 
and DATEPART(year, date_created) = 2009

вернет все даты в апреле. За последний месяц (т. е. до текущего месяца) вы можете использовать GETDATE и DATEADD а также:

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()))

последний месяц считать до последнего дня месяца. 31/01/2016 здесь последний день месяца будет 31 января. который не похож на последние 30 дней.

SELECT CONVERT(DATE, DATEADD(DAY,-DAY(GETDATE()),GETDATE()))
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()))
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 

и еще одно обновление до решения mrdenny.
Это дает точный последний день предыдущего месяца.

declare @PrevMonth as nvarchar(256)

SELECT @PrevMonth = DateName( month,DATEADD(mm, DATEDIFF(mm, 0, getdate()) - 1, 0)) + 
   '-' + substring(DateName( Year, getDate() ) ,3,4)

SQL запрос, чтобы получить запись только за текущий месяц

SELECT * FROM CUSTOMER
WHERE MONTH(DATE) = MONTH(CURRENT_TIMESTAMP) AND YEAR(DATE) = YEAR(CURRENT_TIMESTAMP);

в Sql server за последний месяц:

select * from tablename 
where order_date > DateAdd(WEEK, -1, GETDATE()+1) and order_date<=GETDATE()
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 
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)
WHERE 
    date_created >= DATEADD(MONTH, DATEDIFF(MONTH, 31, CURRENT_TIMESTAMP), 0)
    AND date_created < DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0)

Я из Oracle env, и я бы сделал это так в Oracle:

select * from table
where trunc(somedatefield, 'MONTH') =
trunc(sysdate -INTERVAL '0-1' YEAR TO MONTH, 'MONTH')

идея: я запускаю запланированный отчет предыдущего месяца (от дня 1 до последнего дня месяца, не оконный). Это может быть индекс недружественным, но Oracle имеет быструю обработку даты в любом случае. Есть ли подобный простой и короткий путь в MS SQL? Ответ, сравнивающий год и месяц отдельно, кажется глупым людям Oracle.

вы можете получить записи за последний месяц с этим запросом

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) 

то, как я исправил подобную проблему, было добавлением месяца к моему выберите часть

Month DATEADD(day,Created_Date,'1971/12/31') As Month

и чем я добавил здесь сообщении

Month DATEADD(day,Created_Date,'1971/12/31') = month(getdate())-1