2010-07-21 14 views
35

Ich möchte den ersten Tag jedes entsprechenden Monats des aktuellen Jahres erhalten. Wenn der Benutzer beispielsweise "2010-06-15" auswählt, muss die Abfrage von "2010-06-01" anstelle von "2010-06-15" ausgeführt werden.Wie bekomme ich den ersten Tag eines jeden Monats in mysql?

Bitte helfen Sie mir, wie Sie den ersten Tag vom ausgewählten Datum berechnen. Derzeit versuche ich, wünschenswert mit folgenden mysql SELECT-Abfrage zu erhalten:

Select 
    DAYOFMONTH(hrm_attendanceregister.Date) >= 
    DAYOFMONTH(
    DATE_SUB('2010-07-17', INTERVAL - DAYOFMONTH('2010-07-17') + 1 DAY 
) 
FROM 
    hrm_attendanceregister; 

Dank

Antwort

1

Verwendung date_format Methode und prüfen Sie nur Monat & Jahr

select * from table_name where date_format(date_column, "%Y-%m")="2010-06" 
+0

[Verwenden Sie kein Datumsformat] (http://stackoverflow.com/questions/3298288/how-to-get-first-day-of-ever-corresponding-month-in-mysql/28966866#comment- 46185420), es ist langsam. – Pacerier

62

Ist das, was Sie suchen,:

select CAST(DATE_FORMAT(NOW() ,'%Y-%m-01') as DATE); 
+3

Dies ist unnötiger Overhead. Sie konvertieren das Datum in einen String und dann wieder zurück in das Datum. Meine Lösung ist viel besser. – Pacerier

+1

Das ist viel besser als meine Antwort. – Thomas

-1
select big.* from 
(select @date := '2010-06-15')var 
straight_join 
(select * from your_table where date_column >= concat(year(@date),'-',month(@date),'-01'))big; 

Dadurch wird kein vollständiger Tabellenscan erstellt.

7

können Sie EXTRACT verwenden die Datums Teile, die Sie erhalten möchten:

EXTRACT(YEAR_MONTH FROM DATE('2011-09-28')) 
-- 201109 

Das funktioniert gut für die Gruppierung.

26

Sie die von MySQL zur Verfügung gestellt LAST_DAY Funktion können Sie den letzten Tag eines jeden Monats abzurufen, das ist einfach:

SELECT LAST_DAY('2010-06-15'); 

Wir kommen wieder:

2010-06-30 

Leider hat MySQL bietet keine FIRST_DAY Funktion zum Abrufen des ersten Tages eines Monats (nicht sicher warum). Aber am letzten Tag können Sie einen Tag hinzufügen und einen Monat subtrahieren, um den ersten Tag zu bekommen. So können Sie eine benutzerdefinierte Funktion definieren:

DELIMITER ;; 
CREATE FUNCTION FIRST_DAY(day DATE) 
RETURNS DATE DETERMINISTIC 
BEGIN 
    RETURN ADDDATE(LAST_DAY(SUBDATE(day, INTERVAL 1 MONTH)), 1); 
END;; 
DELIMITER ; 

Auf diese Weise:

SELECT FIRST_DAY('2010-06-15'); 

Wir kommen wieder:

2010-06-01 
+0

Ihre 'FIRST_DAY'-Lösung ist semantisch indirekt, weil Sie einen Tag zum letzten Tag des vorherigen Monats hinzufügen, anstatt einfach die Anzahl der Tage zu subtrahieren, die das aktuelle Datum hat.Siehe meine Lösung. – Pacerier

13

Dieses alte, aber dies könnte für neue menschliche Web-Crawler XD

hilfreich sein

Für den ersten Tag des aktuellen Monats können Sie verwenden:

SELECT LAST_DAY(NOW() - INTERVAL 1 MONTH) + INTERVAL 1 DAY; 
+0

Ineffizient. Verwendet eine Datumssubtraktion und eine Datumsaddition, wenn nur eine Datumssubtraktion benötigt wird. Siehe meine Lösung. – Pacerier

0
date_add(subdate(curdate(), interval day(?) day), interval 1 day) 

ändern Sie die? für das entsprechende Datum

+0

Ineffizient, da Sie eine Datumsaddition und eine Datumssubtraktion verwenden, wenn nur eine Datumssubtraktion erforderlich ist. Auch, [anstelle von 'date_add', verwenden Sie die 2-arity 'AddDate'] (http://stackoverflow.com/a/28966866/632951), die leistungsfähiger ist. – Pacerier

25

Es ist eigentlich eine einfache Lösung, da der erste Tag des Monats today - (day_of_month_in_today - 1) ist einfach:

select now() - interval (day(now())-1) day 

Kontrast, mit dem den other methods der extrem Kreisverkehr und indirekt sind.


Auch, weil wir nicht daran interessiert, in der Zeitkomponente sind, curdate() ist eine bessere (und schneller) Funktion als now(). Wir können auch die 2-Arity-Überlastung subdate() nutzen, da diese performanter ist als die Verwendung interval. So eine bessere Lösung ist:

select subdate(curdate(), (day(curdate())-1)) 
+1

gute Umsetzung des Intervalls – Zordon

+1

gute Antwort, ich denke, das ist die eleganteste und effizienteste Lösung – fthiella

+3

Da Sie schienen, die Lösung aller anderen zu kritisieren, könnten Sie zumindest die Frage selbst beantwortet haben. Die Person fragte nach einem "ausgewählten Datum", nicht nach dem aktuellen Datum. 'SELECT SUBDATE (DATUM ('2010-06-15'), (DAY (DATE ('2010-06-15')) - 1))' – Ray

1

Ich bin überrascht, niemand etwas wie dies vorgeschlagen hat (ich weiß nicht, wie performant es ist):

CONCAT_WS('-', YEAR(CURDATE()), MONTH(CURDATE()), '1') 

Zusätzliche Datum Operationen durchgeführt werden könnten, um Formatieren entfernen, falls erforderlich

2

Sie können die Funktion DATE_FORMAT() verwenden, um den ersten Tag eines Datumsfeldes zu erhalten.

SELECT DATE_FORMAT(CURDATE(),'%Y-%m-01') as FIRST_DAY_CURRENT_MONTH 
FROM dual; 

ändern CURDATE() mit einem anderen Feld Datum wie:

SELECT DATE_FORMAT(purchase_date,'%Y-%m-01') AS FIRST_DAY_SALES_MONTH 
FROM Company.Sales; 

Dann Ihre eigene Frage mit:

SELECT * 
FROM 
    hrm_attendanceregister 
WHERE 
hrm_attendanceregister.Date) >= 
DATE_FORMAT(CURDATE(),'%Y-%m-01') 

Sie können CURDATE() mit einem anderen bestimmten Datum ändern .

0

Das funktioniert gut für mich.

date(SUBDATE("Added Time", INTERVAL (day("Added Time") -1) day)) 

** ersetzen "Added Time" mit Spaltenname

Use Cases:

  1. Wenn Sie alle Datumsfelder außer Monat und Jahr zurücksetzen möchten.

  2. Wenn Sie das Spaltenformat als "Datum" beibehalten möchten. (Nicht als "Text" oder "Nummer")

0

Langsam (17s): SELECT BENCHMARK (100000000, current_date - INTERVAL (Tag (current_date) -1) TAG); SELECT BENCHMARK (100000000, Besetzung (DATE_FORMAT (aktuelles_Datum, '% Y-% m-01') als Datum));

Wenn Sie nicht über ein Datum Art benötigen, ist dieses schneller: Fast (6s): SELECT BENCHMARK (100000000, DATE_FORMAT (CURDATE(), '% Y-% m-01')); SELECT BENCHMARK (100000000, DATE_FORMAT (aktuelles_Datum, '% Y-% m-01'));

Verwandte Themen