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.
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.
Toutes les réponses existantes (de travail) ont l'un des deux problèmes suivants:
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.
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
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
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()))
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()))
declare @PrevMonth as nvarchar(256)
SELECT @PrevMonth = DateName( month,DATEADD(mm, DATEDIFF(mm, 0, getdate()) - 1, 0)) +
'-' + substring(DateName( Year, getDate() ) ,3,4)
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)
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.
WHERE
date_created >= DATEADD(MONTH, DATEDIFF(MONTH, 31, CURRENT_TIMESTAMP), 0)
AND date_created < DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0)
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()))
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);
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.
Une requête simple qui fonctionne pour moi est la suivante:
select * from table où DATEADD (month, 1, DATEFIELD)> = getdate ()
En serveur SQL pour le mois dernier:
select * from tablename
where order_date > DateAdd(WEEK, -1, GETDATE()+1) and order_date<=GETDATE()
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
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)
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