datetime- String formatieren
ha-bauer
- php
0 Bobby0 ha-bauer1 tk0 Bobby0 Vinzenz Mai0 tk
0 tk0 Bobby
0 dedlfix
Hallo zusammen,
ich habe eine kleine Frage bezüglich PHP und mySQL.
Ich habe in der Datenbank einige Blogeinträge. Für ein Archiv will ich nun verschiedene Links erzeugen, die jeweils einen Monat (im Format "MONTH YEAR") repräsentieren; auf Klick sollen darauf alle Einträge dieses Monats erscheinen.
Meine Frage ist nun: Wie schaffe ich es, aus einem String, der im mySQL- Format datetime vorliegt, nur den Monat und das Jahr zu extrahieren und diese im Format "August 2009" (zum Beispiel) auszugeben? Diese Links sollen dabei jedoch nur einmal pro Monat vorliegen, selbst wenn mehrere Einträge vom Monat August 2009 vorliegen.
Ich hoffe, ihr versteht, worauf ich hinaus will.
Danke für jede Antwort und viele Grüße,
ha-bauer
Moin
Du schaffst es mittels den MySQL-date und time Funktionen ein Datum formatiert auszugeben. Dazu eine kleine Function in PHP die englische in deutsche Monatsnamen tauscht und schon bekommst du diese.
Damit die Daten "gruppiert" werden nutze die SQL-Anweisung: GROUP BY
Gruß Bobby
Moin
Du schaffst es mittels den MySQL-date und time Funktionen ein Datum formatiert auszugeben. Dazu eine kleine Function in PHP die englische in deutsche Monatsnamen tauscht und schon bekommst du diese.
Hi Bobby,
danke schonmal für die Antwort. Leider bin ich, was SQL angeht, noch relativ unerfahren. Könntest du mir sagen, wie ich die Abfrage formulieren könnte?
Vielen Dank,
ha-bauer
Moin
danke schonmal für die Antwort. Leider bin ich, was SQL angeht, noch relativ unerfahren. Könntest du mir sagen, wie ich die Abfrage formulieren könnte?
Dann hast du dir meine verlinkte Seite nicht richtig durchgelesen. Probiere bitte erst die Beispiele und poste dann wenn dies nicht funktioniert, wie du es probiert hast. Dann kann ich dir weiterhelfen. Auf der verlinkten Seite stehen viele Beispiele. Versuchs bitte erstmal selbst.
Ein kleiner Hinweis sei gewährt: SELECT "Felder mit Date-Time-Funktion formatiert" FROM TABLE
So in der Art muss dann dein Ergebnis aussehen.
Gruß Bobby
Dann hast du dir meine verlinkte Seite nicht richtig durchgelesen. Probiere bitte erst die Beispiele und poste dann wenn dies nicht funktioniert, wie du es probiert hast. Dann kann ich dir weiterhelfen. Auf der verlinkten Seite stehen viele Beispiele. Versuchs bitte erstmal selbst.
Ein kleiner Hinweis sei gewährt: SELECT "Felder mit Date-Time-Funktion formatiert" FROM TABLE
Hi nochmal,
ich habe es bei den Beispielen mal mit EXTRACT(MONTH FROM '1999-07-02') probiert. Hat auch prima funktioniert, aber als ich dann statt '1999-07-02' meine Spalte 'post_date' angegeben hatte (EXTRACT(MONTH FROM 'post_date')), hat sich mySQL geweigert, mir ein Ergebnis zu liefern. Was mache ich da falsch? Und wie bekomme ich die Gruppierung hin? Da bin ich auch noch nicht hinter gekommen, trotz probierter Beispiele.
Viele Grüße,
ha-bauer
Moin
Hat auch prima funktioniert, aber als ich dann statt '1999-07-02' meine Spalte 'post_date' angegeben hatte (EXTRACT(MONTH FROM 'post_date')), hat sich mySQL geweigert, mir ein Ergebnis zu liefern. Was mache ich da falsch?
Hast du das exact so geschrieben? versuchs mal ohne den Hochkommas.
Und wie bekomme ich die Gruppierung hin? Da bin ich auch noch nicht hinter gekommen, trotz probierter Beispiele.
Was hast du da genau probiert?
Beachte bitte auch den Tip von "tk". Der ist Gold wert.
Gruß Bobby
Hast du das exact so geschrieben? versuchs mal ohne den Hochkommas.
Danke, jetzt funktioniert's. Jetzt bekomme ich eine Menge Zahlen zurück. Kann ich die mit mySQL auch noch in die Monatsnamen umwandeln oder soll ich das mit einem PHP- Array erledigen?
Was hast du da genau probiert?
SELECT EXTRACT(MONTH FROM post_date) GROUP BY post_date
Kleine Frage: Schaffe ich es irgendwie, innerhalb einer Abfrage sowohl den Monat als auch das Jahr zu extrahieren? YEAR_MONTH gibt mir ja das Jahr und den Monat ohne Leerzeichen zurück.
Beachte bitte auch den Tip von "tk". Der ist Gold wert.
Ich will erst mal den Hauptteil der Abfrage hinbekommen. Dann kann ich mich um die Eindeutschung kümmern.
Viele Grüße,
ha-bauer
Hi,
SELECT EXTRACT(MONTH FROM post_date) GROUP BY post_date
Kleine Frage: Schaffe ich es irgendwie, innerhalb einer Abfrage sowohl den Monat als auch das Jahr zu extrahieren?
Kleine Gegenfrage: Schaffst du es sonst, den Inhalt von mehr als nur einer Spalte zu selektieren? (Nein, SELECT * gilt hier nicht als positive Antwort.)
Warum du dich übrigens für EXTRACT entschieden hast, ist mir unverständlich.
Es gibt doch extra Funktionen, die wie Monat und Jahr auf Englisch heissen.
MfG ChrisB
Hi,
SELECT EXTRACT(MONTH FROM post_date) GROUP BY post_date
Kleine Frage: Schaffe ich es irgendwie, innerhalb einer Abfrage sowohl den Monat als auch das Jahr zu extrahieren?Kleine Gegenfrage: Schaffst du es sonst, den Inhalt von mehr als nur einer Spalte zu selektieren? (Nein, SELECT * gilt hier nicht als positive Antwort.)
Nein, aber ich habe es jetzt mal mit
SELECT MONTHNAME(post_date)
probiert. Klappt prima. Wo muss ich denn jetzt
SET lc_time_names = 'de_DE'
hinpacken? Sowohl am Ende als auch am Anfang der Abfrage wirft mir mySQL eine Fehlermeldung aus.
Und wie kann ich das mit GROUP BY einbauen, sodass mir der Monatsnamen jeweils nur noch einmal angezeigt wird?
Ich bin für jede Antwort dankbar.
ha-bauer
Moin
SELECT MONTHNAME(post_date)
probiert. Klappt prima. Wo muss ich denn jetzt
SET lc_time_names = 'de_DE'
hinpacken? Sowohl am Ende als auch am Anfang der Abfrage wirft mir mySQL eine Fehlermeldung aus.
als extra Query muss dies vor der eigentlichen Abfrage abgefeuert werden.
Und wie kann ich das mit GROUP BY einbauen, sodass mir der Monatsnamen jeweils nur noch einmal angezeigt wird?
An die ganze Abfrage kannst du "Group By Spaltenname
" anfügen.
Gruß Bobby
als extra Query muss dies vor der eigentlichen Abfrage abgefeuert werden.
Hat bei mir in PHPMyAdmin nicht funktioniert. Hab erst die SET- Abfrage durchgeführt (mit Erfolgsmeldung) und dann die SELECT- Abfrage, mit dem Ergebnis, dass die Einträge immer noch englisch waren.
An die ganze Abfrage kannst du "Group By
Spaltenname
" anfügen.
Das hat PHPMyAdmin zwar durchgehen lassen, aber es wird trotzdem nicht zusammengefasst, sondern für jeden einzelnen Eintrag der Monatsname ausgegeben.
Hat jemand noch einen Vorschlag?
Vielen Dank,
ha-bauer
P.S. Wie baue ich das ganze eigentlich in eine PHP- Abfrage ein? Mit while() habe ich es schon probiert, hat aber nicht geklappt. Hier mein Code:
echo "<ul>";
$sql_set_time_to_dt = "SET lc_time_names = 'de_DE'";
mysql_query($sql_set_time_to_dt); // Set monthnames to german
$sql_archive = "SELECT MONTHNAME( post_date )
FROM wp_posts
WHERE post_status = 'publish'
AND post_type = 'post'
GROUP BY post_date";
$res = mysql_query($sql_archive);
while ($row = @mysql_fetch_assoc($res)) {
echo "<li>{$row}</li>"; }
echo "</ul>";
Als Ergebnis erhalte ich eine ziemlich lange Liste, wo jedes Listenelement den Namen "Array" hat. Wie kann ich das richtig machen?
Hi,
P.S. Wie baue ich das ganze eigentlich in eine PHP- Abfrage ein?
Wie mache ich dies, wie mache ich jenes, und wie dann das noch ...
Findest du nicht, dass es langsam an der Zeit wäre, dass du erst mal dein Grundlagenwissen etwas erweiterst?
Suche dir ein Tutorial zum Thema, und arbeite es durch.
Als Ergebnis erhalte ich eine ziemlich lange Liste, wo jedes Listenelement den Namen "Array" hat.
mysql_fetch_assoc gibt nun mal ein Array zurück.
Wie kann ich das richtig machen?
Wenn du an den einzelnen Elementen des Arrays interessiert bist, dann greife auf sie zu. Wenn du auch das noch nicht kannst, wird's überhöchste Zeit für's Durcharbeiten eines Grundlagentutorial.
MfG ChrisB
Wenn du an den einzelnen Elementen des Arrays interessiert bist, dann greife auf sie zu.
Würde ich ja gerne (und ich wüsste auch, wie ich es prinzipiell machen würde), aber ich habe doch in diesem Sinne keinen Spaltennamen, den ich abfragen könnte, oder?
ha-bauer
Hi,
Wenn du an den einzelnen Elementen des Arrays interessiert bist, dann greife auf sie zu.
Würde ich ja gerne (und ich wüsste auch, wie ich es prinzipiell machen würde), aber ich habe doch in diesem Sinne keinen Spaltennamen, den ich abfragen könnte, oder?
Dann vergebe einen - Stichwort Alias.
MfG ChrisB
Hallo nochmal,
prima, jetzt habe ich mit AS alles so hinbekommen, wie ich es wollte.
Vielen Dank,
ha-bauer
Moin
prima, jetzt habe ich mit AS alles so hinbekommen, wie ich es wollte.
Und du hast dir vieles selbst erarbeitet anhand von Stichpunkten. Ist das nicht ein tolles Gefühl?
Gruß Bobby
Und du hast dir vieles selbst erarbeitet anhand von Stichpunkten. Ist das nicht ein tolles Gefühl?
Yep.
Viele Grüße,
ha-bauer
Hallo,
Würde ich ja gerne (und ich wüsste auch, wie ich es prinzipiell machen würde), aber ich habe doch in diesem Sinne keinen Spaltennamen, den ich abfragen könnte, oder?
Dann vergib doch einen - »AS« ist dein Freund (siehe Doku).
Grüß,
Tobias
An die ganze Abfrage kannst du "Group By
Spaltenname
" anfügen.
Das hat jetzt geklappt:
SELECT MONTHNAME( post_date )
FROM wp_posts
WHERE post_status = 'publish'
AND post_type = 'post'
GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date
DESC
Bleibt also nur noch die Frage, wie ich das in PHP abfrage, wie ich die Abfrage deutsch hinbekomme (was wahrscheinlich klappt, wenn das eigentliche Query erst mal läuft) und wie ich an den Monatsnamen auch noch das Jahr anhängen kann.
Vielen Dank soweit.
ha-bauer
Hallo,
Neben dem was ChrisB schon schrieb:
als extra Query muss dies vor der eigentlichen Abfrage abgefeuert werden.
Hat bei mir in PHPMyAdmin nicht funktioniert. Hab erst die SET- Abfrage durchgeführt (mit Erfolgsmeldung) und dann die SELECT- Abfrage, mit dem Ergebnis, dass die Einträge immer noch englisch waren.
Der SET
-Query muss in der gleichen Verbindung abgefeuert werden wie der SELECT
-Query - wenn du mit PMA aber erst die Sprache änderst und dann nach dem Neuladen der Seite die Daten holst, sind das zwei verschiedene Verbindungen und MySQL hat längst wieder vergessen, dass es eigentlich die Monate auf deutsch ausgeben soll. Wenn du das Ergebnis mit PMA sehen willst, muss du die beiden Querys im gleichen Fenster mit einem Semikolon getrennt eingeben, PMA trennt die Querys dann auf und schickt sie hintereinander an die Datenbank.
Grüß,
Tobias
Der
SET
-Query muss in der gleichen Verbindung abgefeuert werden wie derSELECT
-Query - wenn du mit PMA aber erst die Sprache änderst und dann nach dem Neuladen der Seite die Daten holst, sind das zwei verschiedene Verbindungen und MySQL hat längst wieder vergessen, dass es eigentlich die Monate auf deutsch ausgeben soll. Wenn du das Ergebnis mit PMA sehen willst, muss du die beiden Querys im gleichen Fenster mit einem Semikolon getrennt eingeben, PMA trennt die Querys dann auf und schickt sie hintereinander an die Datenbank.
Danke für den Tipp, jetzt hat das mit dem Eindeutschen auch geklappt.
ha-bauer
Hallo,
Wo muss ich denn jetzt
SET lc_time_names = 'de_DE'
hinpacken?
Das ist ein eigener Query der vor dem SELECT
-Query per mysql_query() an die Datenbank geschickt werden muss.
Sowohl am Ende als auch am Anfang der Abfrage wirft mir mySQL eine Fehlermeldung aus.
Und die wäre?
Und wie kann ich das mit GROUP BY einbauen, sodass mir der Monatsnamen jeweils nur noch einmal angezeigt wird?
So wie es im Handbuch beschrieben ist.
Grüß,
Tobias
Hallo Bobby,
Du schaffst es mittels den MySQL-date und time Funktionen ein Datum formatiert auszugeben. Dazu eine kleine Function in PHP die englische in deutsche Monatsnamen tauscht und schon bekommst du diese.
PHP brauchst du dafür nicht bemühen - das kann MySQL auch alleine: Einfach vorher den Query
SET lc_time_names = 'de_DE'
abfeuern und schon spuckt MySQL Wochentage und Monate auf deutsch aus, siehe Doku (die englische Doku verwenden, die deutsche ist unvollständig)
Grüß,
Tobias
Moin
PHP brauchst du dafür nicht bemühen - das kann MySQL auch alleine: Einfach vorher den Query
SET lc_time_names = 'de_DE'
abfeuern und schon spuckt MySQL Wochentage und Monate auf deutsch aus, siehe Doku (die englische Doku verwenden, die deutsche ist unvollständig)
Danke für den Tipp. Muss ich mir merken. Kann man direkt nach Festlegung der der Kodierung (UTF-8) standardmäßig abfeuern. Oder spricht was dagegen?
Gruß Bobby
Hallo,
SET lc_time_names = 'de_DE'
abfeuern und schon spuckt MySQL Wochentage und Monate auf deutsch aus, siehe Doku (die englische Doku verwenden, die deutsche ist unvollständig)Danke für den Tipp. Muss ich mir merken.
und die Versionsvoraussetzung beachten :-)
Freundliche Grüße
Vinzenz
Hallo Vinzenz,
SET lc_time_names = 'de_DE'
[...]
und die Versionsvoraussetzung beachten :-)
solange man nicht noch mit einer 4.0er Version rumkrebsen muss sollte das kein Problem sein, die Doku ist an der Stelle nämlich etwas unpräzise: Wenn man sich die Doku zur Version 4.1.x (und kleiner) bzw. zur Version 5.0.x anschaut stellt man fest, dass das das mit lc_time_names auch schon ab Version 4.1.21 bzw. ab 5.0.25 funktioniert ...
Grüß,
Tobias
Hallo Bobby,
Danke für den Tipp. Muss ich mir merken. Kann man direkt nach Festlegung der der Kodierung (UTF-8) standardmäßig abfeuern. Oder spricht was dagegen?
Nein, da spricht imho nichts dagegen - ich feuer den Query auch in der Datenbankklasse direkt nach dem Aufbau der Verbindung ab.
Grüß,
Tobias
Moin
Nein, da spricht imho nichts dagegen - ich feuer den Query auch in der Datenbankklasse direkt nach dem Aufbau der Verbindung ab.
Das habe ich nun auch in selbige standardmäßig integriert.
Gruß Bobby
Hi!
SET lc_time_names = 'de_DE'
Danke für den Tipp. Muss ich mir merken. Kann man direkt nach Festlegung der der Kodierung (UTF-8) standardmäßig abfeuern. Oder spricht was dagegen?
Dagegen kann sprechen, dass du ihn nur in x% deiner Abfragen brauchst, dafür aber beim Rest jedes Mal einen unnötigen Roundtrip vollführst.
Alternative Vorschläge:
Als Administrator und Alleinnutzer kann man den Wert unter init_connect setzen, was automatisch bei jedem Connect und serverseitig und damit ohne Roundtrip passiert.
Als Anwender kann man zumindest mit mysqli_multi_query() einen Roundtrip sparen, wenn man SET NAMES und SET lc_time_names in einem Abwasch erledigt. (Normalerweise sollte man mysql(i)_set_charset() verwenden, aber der Unterschied zu SET NAMES spielt bei Latin1 und UTF-8 keine Rolle.)
Lo!
Moin!
Als Anwender kann man zumindest mit mysqli_multi_query() einen Roundtrip sparen, wenn man SET NAMES und SET lc_time_names in einem Abwasch erledigt. (Normalerweise sollte man mysql(i)_set_charset() verwenden, aber der Unterschied zu SET NAMES spielt bei Latin1 und UTF-8 keine Rolle.)
mysqli_multi_query hat so seine Besonderheiten in der Nutzung. Das kann man nicht analog zu mysqli_query benutzen, ohne die Ergebnisse der einzelnen Abfragen abzuholen.
- Sven Rautenberg
Hi,
Als Anwender kann man zumindest mit mysqli_multi_query() einen Roundtrip sparen, wenn man SET NAMES und SET lc_time_names in einem Abwasch erledigt. (Normalerweise sollte man mysql(i)_set_charset() verwenden, aber der Unterschied zu SET NAMES spielt bei Latin1 und UTF-8 keine Rolle.)
mysqli_multi_query hat so seine Besonderheiten in der Nutzung. Das kann man nicht analog zu mysqli_query benutzen, ohne die Ergebnisse der einzelnen Abfragen abzuholen.
Dann vielleicht doch lieber gleich Zeichenkodierung und Locale schon beim herstellen der Verbindung über mysqli::options angeben.
(Das nimnt doch mehrere Statements durch Semikolon getrennt, oder? Hab's ehrlich gesagt noch nicht mit mehr als einer Anweisung probiert.)
MfG ChrisB
Hi!
mysqli_multi_query hat so seine Besonderheiten in der Nutzung. Das kann man nicht analog zu mysqli_query benutzen, ohne die Ergebnisse der einzelnen Abfragen abzuholen.
Guter Einwand. Danke.
Das ergibt einen "Commands out of sync; you can't run this command now"-Fehler bei den nachfolgenden Querys, wenn man die Ergebnisse nicht abholt.
Dann vielleicht doch lieber gleich Zeichenkodierung und Locale schon beim herstellen der Verbindung über mysqli::options angeben.
Du meinst sicher über die Option MYSQLI_INIT_COMMAND.
(Das nimnt doch mehrere Statements durch Semikolon getrennt, oder? Hab's ehrlich gesagt noch nicht mit mehr als einer Anweisung probiert.)
Ich habe es probiert und es wird abgewiesen. Der Teil nach dem Semikolon wird als syntaktisch falsch beanstandet. In der Konfigurationsdatei MySQLs hingegen kann man im init-connect mehrere Statements angeben.
Lo!