2010-10-18 15 views
24

Ich entwickle gerade eine Anwendung, die Dokumente anzeigt und den Mitgliedern erlaubt, nach diesen Dokumenten nach verschiedenen Parametern zu suchen, von denen einer Datumsbereich ist.Erstelle Datum von Tag, Monat, Jahr in MySQL

Das Problem, das ich habe, ist, dass das Datenbankschema nicht von mir selbst entwickelt wurde und der Ersteller der Datenbank eine 'Datum' Tabelle mit Feldern für 'Tag', 'Monat', 'Jahr' erstellt hat.

Ich möchte gerne wissen, wie ich einen bestimmten Tag, Monat, Jahr aus der Tabelle auswählen und ein Datumsobjekt in SQL erstellen kann, so dass ich die Daten vergleichen kann, die der Benutzer mit BETWEEN eingegeben hat.

Unten ist die Struktur der Datentabelle:

CREATE TABLE IF NOT EXISTS `date` (
    `deposition_id` varchar(11) NOT NULL default '', 
    `day` int(2) default NULL, 
    `month` int(2) default NULL, 
    `year` int(4) default NULL, 
    PRIMARY KEY (`deposition_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 
+8

oh yuk. Warum tun Leute das zu ihren Datenbanken? :-( – Spudley

+0

Ich habe tatsächlich die Datenbank-Tabelle geändert, um ein Datetime-Feld zu erstellen und dann die Jahr-, Monat-, Tag-Felder zu verketten und die Zeilen basierend auf deposition_id zu aktualisieren. Scheint, ein Leckerbissen zu sein. – TGuimond

+0

@Spudley leider ist das nicht ungewöhnlich ... sogar 'crunchbase' api gibt Daten auf diese Weise zurück ... es ist scheiße ...:-( – Optimus

Antwort

27

können Sie STR_TO_DATE()-Funktion verwenden.

+5

STR_TO_DATE (CONCAT ('datum_jahr', '-', LPAD (' datum_month', 2, '00 '),' - ', LPAD ('datum_day', 2, '00')), '% Y -% m-% d ') –

+3

Es ist nicht notwendig, die Ziffern "LPAD" zu verwenden. STR_TO_DATE "erledigt das für Sie:" STR_TO_DATE (CONCAT (Datum_Jahr,' - ', Datum_Monat,' - ', Datum_Tag),'% Y -% m-% d ') ' – pbarney

+0

Nicht sicher, warum SO das Anführungszeichen in eine html-Entität direkt dort ändert – pbarney

1

Versuchen zu verwenden CONCAT() und ein Feld und vergleichen machen.

Bin nicht sicher, dass Sie es als Datum nach der Verkettung vergleichen können.

Sie können als Ganzzahl vergleichen.

concatinate Jahr Monat Tag und machen eine ganze Zahl wie diese 20101017 und vergleichen.

Hoffentlich :)

17

Um eine sortierbare Datumszeichenkette daraus zu erstellen, benötigen Sie CONCAT, um die Bits zusammenzufügen, und LPAD, um sicherzustellen, dass die Felder für Monat und Tag zwei Ziffern lang sind. Etwas wie folgt aus:

CONCAT(`year`,'-',LPAD(`month`,2,'00'),'-',LPAD(`day`,2,'00')) 

Sobald Sie, dass, sollten Sie in der Lage sein BETWEEN zu verwenden, wie sie in einem sortierbar Format sein wird. Wenn Sie sie jedoch noch in tatsächliche Datetime-Felder konvertieren müssen, können Sie das Ganze in UNIX_TIMESTAMP() verpacken, um einen Zeitstempelwert zu erhalten.

So würden Sie mit etwas so enden:

SELECT UNIX_TIMESTAMP(CONCAT(`year`,'-',LPAD(`month`,2,'00'),'-',LPAD(`day`,2,'00'))) as u_date 
WHERE u_date BETWEEN timestamp_1 and timestamp_2 

Beachten Sie jedoch, dass diese massiv langsamer als sein wird, wenn das Feld war nur ein einfacher Zeitstempel in dem ersten Platz. Und Sie sollten auf jeden Fall sicherstellen, dass Sie einen Index für die Felder Jahr, Monat und Tag haben.

33

Wenn Sie ganzzahlige Werte für Jahr, Monat und Tag haben, können Sie DATETIME durch Kombination von MAKEDATE() und DATE_ADD() erstellen. MAKEDATE() mit einem konstanten Tag 1 gibt Ihnen einen DATETIME- für den ersten Tag des Jahres, und dann können Sie es den Monat und den Tag mit DATE_ADD() hinzufügen:

mysql> SELECT MAKEDATE(2013, 1); 
+-------------------+ 
| MAKEDATE(2013, 1) | 
+-------------------+ 
| 2013-01-01  | 
+-------------------+ 

mysql> SELECT DATE_ADD(MAKEDATE(2013, 1), INTERVAL (3)-1 MONTH); 
+---------------------------------------------------+ 
| DATE_ADD(MAKEDATE(2013, 1), INTERVAL (3)-1 MONTH) | 
+---------------------------------------------------+ 
| 2013-03-01          | 
+---------------------------------------------------+ 

mysql> SELECT DATE_ADD(DATE_ADD(MAKEDATE(2013, 1), INTERVAL (3)-1 MONTH), INTERVAL (11)-1 DAY); 
| DATE_ADD(DATE_ADD(MAKEDATE(2013, 1), INTERVAL (3)-1 MONTH), INTERVAL (11)-1 DAY) | 
+----------------------------------------------------------------------------------+ 
| 2013-03-11                  | 
+----------------------------------------------------------------------------------+ 

So ist die Antwort OPs Frage:

SELECT * FROM `date` 
WHERE DATE_ADD(DATE_ADD(MAKEDATE(year, 1), INTERVAL (month)-1 MONTH), INTERVAL (day)-1 DAY) 
BETWEEN '2013-01-01' AND '2014-01-01'; 
+5

Sicher eleganter als das Erstellen und Verwenden von Strings – SEoF

+1

gute Lösung - warum hat MySQL diese native? Das ist ein viel wahrscheinlicher Anwendungsfall als das Jahr mit 100 oder irgendwelchen Tagen –

Verwandte Themen