Requête pour obtenir toutes les lignes du mois précédent

90

Je dois sélectionner toutes les lignes de ma base de données qui ont été créées le mois dernier.

Par exemple, si le mois en cours est janvier, je souhaite renvoyer toutes les lignes créées en décembre, si le mois est février, je souhaite renvoyer toutes les lignes créées en janvier. J'ai une date_createdcolonne dans ma base de données répertoriant les date de création dans ce format: 2007-06-05 14:50:17.

Lewisqic
la source

Réponses:

198
SELECT * FROM table
WHERE YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)
Hobodave
la source
70
SELECT * FROM table WHERE date_created BETWEEN (CURRENT_DATE() - INTERVAL 1 MONTH) AND CURRENT_DATE();
Ghazanfar Mir
12
@GhazanfarMir votre requête ne correspond pas tout à fait à la question, contrairement à la réponse ci-dessus. Le vôtre renvoie les lignes entre ce jour du mois dernier et hier.
Matt Passell
@MattPassell Je suis désolé mais cela betweeninclut les limites. Il inclura également la date actuelle. Pourquoi / comment se limitera-t-il à hier ?? Veuillez préciser?
Ghazanfar Mir
4
Je vois ce que tu veux dire .. Oui tu as raison .. ma requête n'est pas ce que OP voulait .. J'ai mal compris la question
Ghazanfar Mir
Et si current_datece n'est pas aujourd'hui mais une date aléatoire donnée par le client?
dios231 le
22

Voici une autre alternative. En supposant que vous ayez un champ indexé DATEou de DATETIMEtype, celui-ci doit utiliser l'index car les dates formatées seront converties avant l'utilisation de l'index. Vous devriez alors voir une rangerequête plutôt qu'une indexrequête lors de la visualisation avec EXPLAIN .

SELECT
    * 
FROM
    table
WHERE 
    date_created >= DATE_FORMAT( CURRENT_DATE - INTERVAL 1 MONTH, '%Y/%m/01' ) 
AND
    date_created < DATE_FORMAT( CURRENT_DATE, '%Y/%m/01' )
Martin Clayton
la source
+1. Beaucoup plus convivial pour les index. Vous pouvez également lancer un STR_TO_DATEautour du DATE_FORMATafin qu'il traite toujours des objets de date.
Leigh
14

S'il n'y a pas de dates futures ...

SELECT * 
FROM   table_name 
WHERE  date_created > (NOW() - INTERVAL 1 MONTH);

Testé.

Ekerner
la source
3
Je pense qu'ils cherchaient quelque chose de différent. c'est-à-dire tous les enregistrements du mois dernier (c'est-à-dire du 1er octobre au 31 octobre 2012 23:59:59). La requête ci-dessus renverrait les 30 derniers jours environ, à partir de la date et de l' heure d'aujourd'hui .
Leigh
13

Alternativement à la réponse d' Hobodave

SELECT * FROM table
WHERE YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)

Vous pouvez obtenir la même chose avec EXTRACT, en utilisant YEAR_MONTH comme unité, vous n'aurez donc pas besoin du AND, comme ceci:

SELECT * FROM table
WHERE EXTRACT(YEAR_MONTH FROM date_created) = EXTRACT(YEAR_MONTH FROM CURDATE() - INTERVAL
1 MONTH)
SMTF
la source
Cela fonctionne très bien pendant des mois, mais malheureusement, il n'y a pas d' YEAR_WEEK intervalle temporel , vous devrez donc vous rabattre sur la réponse de hobodave si vous avez besoin de semaines au lieu de mois.
Danny Beckett le
8
SELECT *
FROM  yourtable
where DATE_FORMAT(date_created, '%Y-%m') = date_format(DATE_SUB(curdate(), INTERVAL 1 month),'%Y-%m')

Cela devrait renvoyer tous les enregistrements du mois civil précédent, par opposition aux enregistrements des 30 ou 31 derniers jours.

Gregg
la source
J'ai oublié de mentionner ... cela devrait renvoyer tous les enregistrements du mois civil précédent, par opposition aux enregistrements des 30 ou 31 derniers jours.
Gregg
À mon avis, cela devrait être la réponse acceptée car elle est plus simple que la réponse acceptée mais fournit le même résultat
Grant
3

Même si la réponse à cette question a déjà été sélectionnée, je pense que la requête la plus simple sera

SELECT * 
FROM table 
WHERE 
date_created BETWEEN (CURRENT_DATE() - INTERVAL 1 MONTH) AND CURRENT_DATE();
Ghazanfar Mir
la source
2
Non, pas tout à fait. Voir ma réponse à votre commentaire sur la réponse donnée par @hobodave
Matt Passell
@MattPassell Vous avez raison, j'ai mal compris la question .. J'ai raté le point que le résultat ne devrait être limité qu'aux enregistrements du mois dernier.
Ghazanfar Mir
2
WHERE created_date >= DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL 2 MONTH)), INTERVAL 1 DAY) 
  AND created_date <= DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL 1 MONTH)), INTERVAL 0 DAY) 

Cela a fonctionné pour moi (sélectionne tous les enregistrements créés le mois dernier, quel que soit le jour où vous exécutez la requête ce mois-ci)

Giles
la source
1

select fields FROM table WHERE date_created LIKE concat(LEFT(DATE_SUB(NOW(), interval 1 month),7),'%');

celui-ci pourra profiter d'un index si votre date_created est indexé, car il n'applique aucune fonction de transformation à la valeur du champ.

Ggiroux
la source
@ggiroux - Il doit cependant convertir la date en type de caractère avant d'appliquer le LIKE.
martin clayton
oui en effet, mais toujours une amélioration par rapport à la réponse sélectionnée IMHO (IFF date_created est indexé)
ggiroux
1

Voici la requête pour obtenir les enregistrements du mois dernier:

SELECT *
FROM `tablename`
WHERE `datefiled`
BETWEEN DATE_SUB( DATE( NOW( ) ) , INTERVAL 1
MONTH )
AND 
LAST_DAY( DATE_SUB( DATE( NOW( ) ) , INTERVAL 1
MONTH ) )

Cordialement - SAQIB

saqib jahangir Pakistan
la source
Avez-vous essayé d'exécuter cette requête? Pour autant que je vois, il ne sélectionnerait pas toutes les dates des mois précédents (comme dans: renvoyer les données de janvier tout au long de février), mais renvoyer les données d'une plage commençant le même jour il y a un mois
Nico Haase
0

Alternative à condition unique

SELECT * FROM table
WHERE YEAR(date_created) * 12 + MONTH(date_created)
    = YEAR(CURRENT_DATE) * 12 + MONTH(CURRENT_DATE) - 1
kcsoft
la source
-1
SELECT *  FROM table  
WHERE  YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)
sid busa
la source
Avez-vous essayé d'exécuter cette requête? Pour autant que je vois, il ne sélectionnerait pas toutes les dates des mois précédents (comme dans: renvoyer les données de janvier tout au long de février), mais renvoyer les données d'une plage commençant le même jour il y a un mois
Nico Haase
J'ai eu quelques changements, vérifiez maintenant que ça marche ou pas
Sid Busa