web-dev-qa-db-fra.com

Obtenir les enregistrements du mois dernier sur le serveur SQL

Je souhaite obtenir les enregistrements du mois dernier en fonction du champ "date_created" de ma table db [membre].

Quel est le SQL pour faire cela?

Pour plus de précision, le mois dernier - du 1/8/2009 au 31/8/2009

Si aujourd'hui est le 01/03/2010, il me faudra obtenir les enregistrements du 01/12/2009 au 31/12/2009.

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

Vous devez vérifier le mois et l'année.

89
Dave Barker

Toutes les réponses existantes (de travail) ont l'un des deux problèmes suivants:

  1. Ils ignoreront les index sur la colonne recherchée
  2. La volonté (potentiellement) sélectionner des données qui ne sont pas prévues, corrompant silencieusement vos résultats.

1. Indices ignorés:

Dans la plupart des cas, lorsqu'une fonction recherchée est associée à une colonne (y compris implicitement, comme pour CAST), l'optimiseur doit ignorer les index de la colonne et effectuer une recherche dans chaque enregistrement. Voici un exemple rapide:

Nous avons affaire à des horodatages, et la plupart des SGBDR ont tendance à stocker ces informations sous la forme d'une valeur croissante, généralement un nombre long ou BIGINTEGER de nanosecondes. L'heure actuelle ressemble donc/est stockée comme ceci:

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

Vous ne voyez pas la valeur 'Year' ('2014') dedans, n'est-ce pas? En fait, il y a pas mal de calculs compliqués à traduire. Ainsi, si vous appelez l’une des fonctions d’extraction/date de la colonne recherchée, le serveur doit effectuer tous ces calculs pour déterminer s’il est possible de l’inclure dans les résultats. Sur les petites tables, ce n'est pas un problème, mais à mesure que le pourcentage de lignes sélectionnées diminue, cela devient un drain de plus en plus grand. Ensuite, dans ce cas, vous le faites une seconde fois pour poser des questions sur MONTH... eh bien, vous obtenez la photo.

2. Données non souhaitées:

En fonction de la version de SQL Server et des types de données de colonne utilisés, utilisez BETWEEN (ou des plages similaires supérieures comprises: <=) peut entraîner la sélection de données incorrectes . Essentiellement, vous finissez potentiellement par inclure les données de minuit du jour "suivant" ou en excluant une partie des enregistrements du jour "en cours".

Ce que vous devriez faire:

Nous avons donc besoin d’un moyen sûr pour nos données et d’utiliser des indices (s’ils sont viables). La manière correcte est alors de la forme:

WHERE date_created >= @startOfPreviousMonth AND date_created < @startOfCurrentMonth

Étant donné qu’il n’ya qu’un mois, @startOfPreviousMonth peut facilement être remplacé par/obtenu par:

DATEADD(month, -1, @startOCurrentfMonth)

Si vous devez extraire le début du mois en cours sur le serveur, vous pouvez le faire via les éléments suivants:

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

Un mot rapide d'explication ici. La DATEDIFF(...) initiale obtiendra la différence entre le début de l'ère actuelle (0001-01-01 - AD, CE, etc.), renvoyant essentiellement un grand entier. Il s'agit du nombre de mois jusqu'au début du mois actuel. Nous ajoutons ensuite ce nombre au début de l'ère, qui se situe au début du mois donné.

Donc, votre script complet pourrait/devrait ressembler à ceci:

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

Toutes les opérations sur les dates ne sont donc effectuées qu'une fois, sur une valeur; l'optimiseur est libre d'utiliser des index et aucune donnée incorrecte ne sera incluse.

75
Clockwork-Muse

Ajouter les options fournies jusqu'à présent n'utilisera pas du tout vos index.

Quelque chose comme cela fera l'affaire, et utilisera un index sur la table (s'il en existe un).

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

Une mise à niveau de la solution de mrdenny, de cette façon, vous obtenez exactement le mois dernier de AAAA-MM-01 

9
Rokas

Le mois dernier, considérez que vous êtes jusqu'au dernier jour du mois . 31/01/2016 Le dernier jour du mois serait le 31 janvier, ce qui n’est pas similaire aux 30 derniers jours.

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

Une façon de le faire est d'utiliser la fonction DATEPART :

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

reviendra toutes les dates en avril. Pour le dernier mois (c'est-à-dire avant le mois en cours), vous pouvez également utiliser GETDATE et 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()))
2
Vinko Vrsalovic
declare @PrevMonth as nvarchar(256)

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

Vous pouvez obtenir les enregistrements du dernier mois avec cette requête 

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

et une autre mise à niveau de la solution de mrdenny.
Il indique également le dernier jour exact du mois précédent.

1
Dorothy
WHERE 
    date_created >= DATEADD(MONTH, DATEDIFF(MONTH, 31, CURRENT_TIMESTAMP), 0)
    AND date_created < DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0)
1
Kostya
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
DmitryK

Requête SQL pour obtenir un enregistrement du mois en cours uniquement

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

Je viens d'Oracle et je le ferais comme ceci dans Oracle:

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

Idée: le rapport du mois précédent est programmé (du jour 1 au dernier jour du mois, sans fenêtre). Cela pourrait être index peu amical, mais Oracle a quand même un traitement rapide des dates .. Est-ce qu'il existe un moyen simple et court similaire dans MS SQL? La réponse comparant année et mois séparément semble ridicule aux gens d’Oracle.

1
ant

Une requête simple qui fonctionne pour moi est la suivante:

select * from table où DATEADD (month, 1, DATEFIELD)> = getdate ()

0
Harkeet Bajaj

En serveur SQL pour le mois dernier:

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

J'ai résolu le même problème en ajoutant Month à mySELECTportion

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

et que j'ai ajoutéO&UGRAVE;déclaration

Month DATEADD(day,Created_Date,'1971/12/31') = month(getdate())-1
0
Kalenji
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 
0
Kranti Singh
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)
0

Si vous cherchez le mois dernier, essayez ceci,

SELECT
FROM  #emp 
WHERE DATEDIFF(MONTH,CREATEDDATE,GETDATE()) = 1

Si vous cherchez le mois dernier, essayez ceci,

SELECT
FROM #emp
WHERE DATEDIFF(day,CREATEDDATE,GETDATE()) between 1 and 30
0
RIJWAN KASSAR