Obter os registros do último mês no servidor SQL

Eu quero obter os registros do mês passado com base no meu campo [membro] da tabela de database “date_created”.

Qual é o sql para fazer isso?

Para esclarecimento, no último mês – 1/8/2009 a 31/8/2009

Se hoje for 01/03/2010, precisarei obter os registros de 1/12/2009 a 31/12/2009.

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

Você precisa verificar o mês e o ano.

Todas as respostas existentes (em funcionamento) apresentam um dos dois problemas:

  1. Eles vão ignorar índices na coluna que está sendo pesquisada
  2. A vontade (potencialmente) seleciona dados que não são intencionais, corrompendo silenciosamente seus resultados.

1. Índices ignorados:

Na maioria das vezes, quando uma coluna que está sendo pesquisada tem uma function chamada (incluindo implicitamente, como para CAST ), o otimizador deve ignorar os índices na coluna e pesquisar em cada registro. Aqui está um exemplo rápido:

Estamos lidando com registros de data e hora e a maioria dos RDBMSs tendem a armazenar essas informações como um valor crescente de algum tipo, geralmente uma contagem long ou BIGINTEGER de mili- / nanossegundos. A hora atual assim parece / é armazenada assim:

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

Você não vê o valor de ‘Ano’ ( '2014' ) aí, não é? Na verdade, há um pouco de matemática complicada para traduzir de um lado para outro. Portanto, se você chamar qualquer uma das funções de extração / parte da data na coluna pesquisada, o servidor terá que executar toda essa matemática apenas para descobrir se você pode incluí-la nos resultados. Em tabelas pequenas, isso não é um problema, mas à medida que a porcentagem de linhas selecionadas diminui, isso se torna um dreno cada vez maior. Então, neste caso, você está fazendo isso uma segunda vez para perguntar sobre o MONTH … bem, você começa a foto.

2. Dados não intencionais:

Dependendo da versão específica do SQL Server e dos tipos de dados da coluna, o uso de BETWEEN (ou intervalos de limite superior inclusivos semelhantes: <= ) pode resultar na seleção de dados incorretos . Essencialmente, você acaba incluindo dados da meia-noite do dia "seguinte" ou excluindo parte dos registros do dia "atual".

O que você deveria fazer:

Portanto, precisamos de uma maneira segura para nossos dados e usaremos índices (se viáveis). A maneira correta é então da forma:

 WHERE date_created >= @startOfPreviousMonth AND date_created < @startOfCurrentMonth 

Dado que há apenas um mês, @startOfPreviousMonth pode ser facilmente substituído por / derivado por:

 DATEADD(month, -1, @startOCurrentfMonth) 

Se você precisar derivar o início do mês atual no servidor, poderá fazê-lo do seguinte modo:

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

Uma palavra rápida de explicação aqui. O DATEDIFF(...) inicial DATEDIFF(...) terá a diferença entre o início da era atual ( 0001-01-01 - AD, CE, qualquer que seja), retornando essencialmente um inteiro grande. Esta é a contagem de meses até o início do mês atual . Em seguida, adicionamos esse número ao início da era, que é no início do mês determinado.

Portanto, seu script completo pode / deve ser semelhante ao seguinte:

 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 

Todas as operações de data são, portanto, realizadas apenas uma vez, em um valor; o otimizador está livre para usar índices e nenhum dado incorreto será incluído.

Adicionar as opções que foram fornecidas até agora não usará seus índices.

Algo como isso fará o truque e fará uso de um índice na tabela (se existir).

 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 

Uma atualização para a solução de mrdenny, desta forma você começa exatamente no mês passado de AAAA-MM-01

Uma maneira de fazer isso é usar a function DATEPART :

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

retornará todas as datas em abril. No mês passado (ou seja, anterior ao mês atual), você também pode usar GETDATE e 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())) 

No mês passado, considere até o último dia do mês. 31/01/2016 aqui último dia do mês seria 31 de janeiro, o que não é semelhante aos últimos 30 dias.

 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 

e outra atualização para a solução de mrdenny.
Dá o último dia exato do mês anterior também.

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

Consulta SQL para obter apenas o registro do mês atual

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

No servidor SQL para o último mês:

 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) 

Eu sou do Oracle env e gostaria de fazer assim no Oracle:

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

Idéia: estou executando um relatório programado do mês anterior (do dia 1 até o último dia do mês, sem janelas). Isso pode ser indexado de forma hostil, mas a Oracle tem manipulação de data rápida de qualquer maneira. Existe um caminho simples e curto semelhante no MS SQL? A resposta que compara ano e mês separadamente parece boba para o pessoal da Oracle.

Você pode obter os registros do último mês com 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) 

A maneira como consertei um problema semelhante foi adicionando Mês à minha parte SELECT

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

e que eu adicionei a declaração WHERE

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