Query per ottenere tutte le righe del mese precedente


92

Devo selezionare tutte le righe nel mio database che sono state create il mese scorso.

Ad esempio, se il mese corrente è gennaio, desidero restituire tutte le righe create a dicembre, se il mese è febbraio, desidero restituire tutte le righe create a gennaio. Ho un date_createdcolonna nel mio database che elenca la data creato in questo formato: 2007-06-05 14:50:17.

Risposte:


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

70
SELECT * FROM table WHERE date_created BETWEEN (CURRENT_DATE() - INTERVAL 1 MONTH) AND CURRENT_DATE();
Ghazanfar Mir

12
@GhazanfarMir la tua domanda non corrisponde esattamente alla domanda, mentre la risposta sopra sì. Yours restituisce le righe comprese tra questo giorno del mese scorso fino a ieri.
Matt Passell

@ MattPassell Mi dispiace ma betweenè comprensivo dei limiti .. Includerà anche la data corrente. Perché / come sarà limitato a ieri ?? Per favore approfondisci?
Ghazanfar Mir

5
Capisco cosa intendi .. Sì, hai ragione .. la mia domanda non è ciò che voleva OP .. Ho frainteso la domanda
Ghazanfar Mir

e se il current_datenon è oggi ma una data casuale data dal cliente?
dios231

23

Ecco un'altra alternativa. Supponendo che tu abbia un campo indicizzato DATEo di DATETIMEtipo, questo dovrebbe utilizzare l'indice poiché le date formattate verranno convertite in tipo prima dell'utilizzo dell'indice. Dovresti quindi vedere una rangequery anziché una indexquery quando visualizzata con 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' )

+1. Molto più indicizzato. Puoi anche lanciare un STR_TO_DATEgiro in DATE_FORMATmodo che abbia sempre a che fare con oggetti data.
Leigh

15

Se non ci sono date future ...

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

Testato.


3
Penso che stessero cercando qualcosa di diverso. vale a dire Tutti i record del mese scorso (cioè 1 ottobre - 31 ottobre 2012 23:59:59). La query precedente restituirà gli ultimi circa 30 giorni, dalla data e dall'ora odierne .
Leigh

13

In alternativa alla risposta di hobodave

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

Potresti ottenere lo stesso con EXTRACT, usando YEAR_MONTH come unità, quindi non avresti bisogno dell'AND, in questo modo:

SELECT * FROM table
WHERE EXTRACT(YEAR_MONTH FROM date_created) = EXTRACT(YEAR_MONTH FROM CURDATE() - INTERVAL
1 MONTH)

Funziona benissimo per mesi, ma sfortunatamente non c'è YEAR_WEEK un intervallo temporale , quindi dovresti tornare alla risposta di hobodave se hai bisogno di settimane invece di mesi.
Danny Beckett

8
SELECT *
FROM  yourtable
where DATE_FORMAT(date_created, '%Y-%m') = date_format(DATE_SUB(curdate(), INTERVAL 1 month),'%Y-%m')

Ciò dovrebbe restituire tutti i record del mese di calendario precedente, rispetto ai record degli ultimi 30 o 31 giorni.


Ho dimenticato di menzionare ... questo dovrebbe restituire tutti i record del mese di calendario precedente, a differenza dei record degli ultimi 30 o 31 giorni.
Gregg

A mio parere questa dovrebbe essere la risposta accettata in quanto è più semplice della risposta accettata ma fornisce lo stesso risultato
Grant

3

Anche se la risposta a questa domanda è già stata selezionata, tuttavia, credo che la domanda più semplice lo sarà

SELECT * 
FROM table 
WHERE 
date_created BETWEEN (CURRENT_DATE() - INTERVAL 1 MONTH) AND CURRENT_DATE();

2
No, non proprio. Vedi la mia risposta al tuo commento sulla risposta data da @hobodave
Matt Passell

@ MattPassell Hai ragione, ho capito male la domanda .. Ho perso il punto che il risultato dovrebbe essere limitato solo ai record SOLO dal mese scorso.
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) 

Questo ha funzionato per me (seleziona tutti i record creati dal mese scorso, indipendentemente dal giorno in cui hai eseguito la query questo mese)


1

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

questo sarà in grado di sfruttare un indice se il tuo date_created è indicizzato, perché non applica alcuna funzione di trasformazione al valore del campo.


@ggiroux - Tuttavia, deve convertire la data in un tipo di carattere prima di applicare il LIKE.
martin clayton

sì in effetti, ma ancora un miglioramento rispetto alla risposta selezionata IMHO (IFF date_created è indicizzato)
ggiroux

1

Ecco la query per ottenere i record dell'ultimo mese:

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

Saluti - saqib


Hai provato a eseguire quella query? Per quanto mi risulta, non selezionerebbe tutte le date dei mesi precedenti (come in: restituisce i dati da gennaio per tutto febbraio), ma restituisce i dati da un intervallo che inizia lo stesso giorno di un mese fa
Nico Haase,

0

Alternativa con condizione unica

SELECT * FROM table
WHERE YEAR(date_created) * 12 + MONTH(date_created)
    = YEAR(CURRENT_DATE) * 12 + MONTH(CURRENT_DATE) - 1

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

Hai provato a eseguire quella query? Per quanto ne so, non selezionerebbe tutte le date dei mesi precedenti (come in: restituisce i dati da gennaio per tutto febbraio), ma restituisce i dati da un intervallo che inizia lo stesso giorno di un mese fa
Nico Haase,

Ho fatto poche modifiche, controlla ora che funzioni o meno
Sid busa
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.