Подтвердить что ты не робот

Получить записи за последний месяц на SQL-сервере

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

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

Для уточнения, в прошлом месяце - с 1/8/2009 по 31/8/2009

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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

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

Мы имеем дело со временными метками, и большинство РСУБД имеют тенденцию хранить эту информацию как возрастающую ценность какого-либо типа, обычно это число 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, что угодно), по существу возвращающим большое целое число. Это количество месяцев до начала текущего месяца. Затем мы добавим этот номер в начало эры, которая находится в начале данного месяца.

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

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

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

Ответ 3

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

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

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

Ответ 4

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

Ответ 5

Один из способов сделать это - использовать функцию 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()))

Ответ 6

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

Ответ 7

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.
Он также дает последний день предыдущего месяца.

Ответ 8

declare @PrevMonth as nvarchar(256)

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

Ответ 9

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

SELECT CONVERT(DATE, DATEADD(DAY,-DAY(GETDATE()),GETDATE()))

Ответ 10

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

select * from tablename 
where order_date > DateAdd(WEEK, -1, GETDATE()+1) and order_date<=GETDATE()

Ответ 11

WHERE 
    date_created >= DATEADD(MONTH, DATEDIFF(MONTH, 31, CURRENT_TIMESTAMP), 0)
    AND date_created < DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0)

Ответ 12

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 

Ответ 13

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)

Ответ 14

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

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

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

Ответ 15

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

SELECT * FROM dbo.member d WHERE CONVERT (DATE, date_created, 101) >= CONVERT (DATE, DATEADD (m, dateiff (m, 0, current_timestamp) -1, 0)) и CONVERT (DATE, date_created, 101) < CONVERT (DATE, DATEADD (m, dateiff (m, 0, current_timestamp) -1, 0), 101)