2010-01-19 16 views
54

Należy wybrać wszystkie wiersze w mojej bazie danych, które zostały utworzone w zeszłym miesiącu.MySQL: Zapytanie, aby uzyskać wszystkie wiersze z poprzedniego miesiąca

Na przykład, jeśli bieżący miesiąc to styczeń, to chcę zwrócić wszystkie wiersze utworzone w grudniu, jeśli miesiąc to luty, a następnie chcę zwrócić wszystkie wiersze utworzone w styczniu. Mam kolumnę date_created w mojej bazie danych, która zawiera datę utworzoną w tym formacie: 2007-06-05 14:50:17.

Odpowiedz

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

'SELECT * FROM tabela WHERE DATE_CREATED MIĘDZY (CURRENT_DATE() - przedział 1 miesiąc) i CURRENT_DATE();' –

+3

@GhazanfarMir zapytanie nie całkiem pasuje do pytania, podczas gdy odpowiedź powyżej, nie. Twój zwraca wiersze między tym dniem, a ostatnim miesiącem, do wczoraj. –

+0

@MattPassell Przykro mi, ale 'między" zawiera granice. Zawiera również bieżącą datę. Dlaczego/Jak będzie ograniczone do wczoraj? Proszę rozwinąć? –

0

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

ten będzie mógł skorzystać z indeksu, jeśli DATE_CREATED jest indeksowana, ponieważ nie stosuje się żadnej funkcji transformacji wartości pola.

+0

@ggiroux - Konieczne jest przekonwertowanie daty na typ postaci przed zastosowaniem LIKE. –

+0

tak, ale wciąż poprawa w stosunku do wybranej odpowiedzi IMHO (IFF data_created jest indeksowana) – ggiroux

16

Oto kolejna alternatywa. Zakładając, że masz indeksowane pole typu DATE lub DATETIME, powinno się użyć indeksu, ponieważ sformatowane daty będą konwertowane na typ przed użyciem indeksu. Powinieneś wtedy zobaczyć zapytanie o adres URL: range, a nie zapytanie index po wyświetleniu z 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

to dostarczy ci zapisy, które zostały utworzone pierwszego dnia bieżącego miesiąca. – ggiroux

+0

@ggiroux - Rzeczywiście. Dzięki - naprawione. –

+0

+1 wtedy - znacznie czystszy niż mój :) – ggiroux

9

Jeśli istnieją żadne przyszłe terminy ...

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

Testowany.

+1

Myślę, że szukali czegoś innego. tj. Wszystkie zapisy z ostatniego miesiąca (tj. 1 października - 31 października 2012 roku 23:59:59). Powyższe zapytanie zwróci ostatnie około 30 dni, od dzisiejszej daty i * godziny *. – Leigh

8

Alternatywnie do hobodave's answer

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

Można osiągnąć to samo z wyciągiem, używając YEAR_MONTH jako jednostki, a tym samym nie musiałyby AND, tak:

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

chociaż odpowiedź na to pytanie zostało już wybrane, jednak uważam, że najprostsze zapytanie będzie

+1

Nie, niezupełnie. Zobacz moją odpowiedź na Twój komentarz do odpowiedzi udzielonej przez @hobodave –

+0

@MattPassell Masz rację, źle zrozumiałem pytanie .. Brakowało mi punktu, w którym wynik powinien być ograniczony tylko do rekordów TYLKO z zeszłego miesiąca. –

1

Oto zapytanie, aby uzyskać rekordy ostatniego miesiąca:

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

Pozdrowienia - Saqib

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

Ten pracował dla mnie (Wybiera wszystkie rekordy utworzone z ostatniego miesiąca, niezależnie od dnia, w którym uruchom zapytanie w tym miesiącu)

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

Powinno to zwrócić wszystkie zapisy z poprzedniego miesiąca kalendarzowego, w przeciwieństwie do rekordów z ostatnich 30 lub 31 dni.

+0

Zapomniałem wspomnieć ... powinno to zwrócić wszystkie zapisy z poprzedniego miesiąca kalendarzowego, w przeciwieństwie do zapisów z ostatnich 30 lub 31 dni. – Gregg

+0

Moim zdaniem powinno to być zaakceptowaną odpowiedzią, ponieważ jest prostsza niż zaakceptowana odpowiedź, ale zapewnia taki sam wynik – Grant

Powiązane problemy