1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

MYSQL Abfrageergbnis weiterverarbeiten Datum-Problem

Dieses Thema im Forum "PHP" wurde erstellt von Tja_was, 24. November 2016.

  1. Tja_was

    Tja_was Grünschnabel

    Hallo,
    ich versuche jetzt seit Wochen verzweifelt eine Lösung für mein Problem zu finden..
    Ich habe in meiner Datenbank eine Tabelle "post_meta". In dieser befinden sich 4 Spalten. in einer Spalte befinden sich Angaben wie Datum, Name, etc. Ich schaffe es die gewünschten Daten zu Filtern und erhalte im Grunde schon ein zufriedenstellendes Ergebnis. ABER:
    Wie kann ich aus diesem Ergebnis weiter Filtern? Sprich ich bekomme im Moment den Kundennamen, Kundenkontakt und ein Erinnerungsdatum. Ich möchte eine Email mit den entsprechenden Daten ausgehend vom Erinnerungsdatum - 100 Tage. Leider kann ich es nicht weiter filtern.

    Hier mal einer meiner vielen Ansätze:
    PHP:
    1. $sql= "meta_value, post_id FROM di0n8s_postmeta WHERE meta_key='name' OR meta_key='kontakt' OR meta_key='start-datum' OR meta_key='befuellung-neu' ORDER BY post_id";
    2. $suchdatum = new DateTime("-100 days");
    3. echo $suchdatum->format("d-m-Y");

    Nur wie bekomme ich das kombiniert oder muss ich mit create temporary table arbeiten?

    Auch das war ein Ansatz:
    PHP:
    1. $suchdatum = new DateTime("-100 days");
    2. echo $suchdatum->format("d-m-Y"); (Ergebnis: 16-08-2016 - wäre ja richtig in der Formatierung)
    3. $query = "SELECT meta_value, post_id FROM wb16_postmeta WHERE meta_key='start-datum'AND DATEDIFF(NOW(), 'post_date') > 11";

    Funktioniert leider auch nicht.. Wo ist denn nur mein Denkfehler?

    Hier meine Tabelle - ein Ausschnitt..

    tabelle.jpg

    Wenn ich versuche das Ganze gleich nach Datum zu durchsuchen:

    PHP:
    1. $suchdatum = new DateTime("-100 days");
    2. echo $suchdatum->format("d-m-Y");
    3. $query = "SELECT meta_value, post_id FROM wb16_postmeta WHERE meta_key='start-datum' LIKE '$suchdatum'";

    erhalte ich folgende Fehlermeldung:
    Catchable fatal error: Object of class DateTime could not be converted to string

    Was ja logisch ist, da das Feld nicht als Datum formatiert ist..

    Ich hoffe ich konnte mich einigermaßen Verständlich ausdrücken.. [​IMG]

    Über jede Hilfe bin ich dankbar. Google hab ich auch schon befragt, aber mir fehlt einfach der Ansatz..

    Gruß,
    Tanja
     
  2. sheel

    sheel I love Asm Administrator

    Hi

    Etwas ist mir nicht ganz klar: Das heutige Datum minus 100 Tage muss was genau sein? Gleich wie start-datum, älter als start-datum, ...?

    Angenommen "gleich wie" ist das Ziel, und der Wert in der DB ist wirklich immer im richtigen Format:
    Code (SQL):
    1. SELECT meta_value, post_id FROM wb16_postmeta WHERE meta_key='start-datum'
    2. AND DATEDIFF(CURDATE(),STR_TO_DATE(meta_value,'%d-%m-%Y'))=100
     
  3. Yaslaw

    Yaslaw n/a Moderator

    Ich nehme nur dein letzter Versuch. sonst wirds unübersichtlich
    Code (PHP):
    1. $query = "SELECT meta_value, post_id FROM wb16_postmeta WHERE meta_key='start-datum' LIKE '$suchdatum'";
    Code (Text):
    1. WHERE feld1 = 'value2' LIKE 'value2'
    2. Das ist ein komisches WHERE. So müsste es sein
    3. WHERE feld1 = 'value2' AND feld2 LIKE 'value2'
    In deinem Fall auch kein LIKE

    Dann noch den String ausgeben und nicht die Klasse
    Code (PHP):
    1. $dateString = $suchdatum->format("d-m-Y");
    2. $query = "SELECT meta_value, post_id FROM wb16_postmeta WHERE meta_key='start-datum' and meta_value = '$dateString'";

    Zudem ist die Spalte meta_value auch nicht als Datum sondern als String hitnerlegt. In deinem Fall gegen die SQL-Regel Y-m-d hast du d-m-Y. Du musst einfach noch mit STR_TO_DATE ein Datum daraus machen. Das ist wichtig, wenn man damit rechnen will.
    Code (SQL):
    1. STR_TO_DATE('24-11-2016', '%d-%m-%Y')
    Also drehen wir bereits bei dem $suchdatum->format() das Fromat um.
    Zudem den Wert aus der Tabelle wie oben erwähnt in ein Datum wandeln.

    Jetzt willst du alle die die Datum-100 Tage
    Code (PHP):
    1. $dateString = $suchdatum->format("Y-m-d");
    2. $query = "
    3.    SELECT
    4.        meta_value,
    5.        post_id
    6.    FROM wb16_postmeta
    7.    WHERE
    8.        meta_key='start-datum'
    9.        AND STR_TO_DATE(meta_value, '%d-%m-%Y') >= DATE_SUB('$dateString', INTERVAL 100 DAY)"
    Das ganze ist natürlich ungetestet und ohne Gewehr
     
  4. Tja_was

    Tja_was Grünschnabel

    Vielen Dank ersteinmal!
    Zum Verständnis:
    @sheel
    Also das Problem ist ich habe eine Datenbank mit ca. 1200 Kundendaten. Jeder Kunde soll per mail erinnert werden. Dazu brauche ich zwei Abfragen. Einmal nach 6 Monaten und einmal nach 12 Monaten rückwärts gerechnet von start-datum. Das Start datum ist eigentlich nur das Eingabedatum wann der Kunde eingetragen wurde. Also der Kunde soll in 6 bzw. 12 Monaten erinnert werden. Ich habe zum probieren erstmal minus 100 Tage (-100) genommen.
    Das ganze ist in WordPress verpackt und leider ist das Datum nicht als Datum in der Tabelle eingetragen... da ist gar keine Angabe. Und wenn ich versuche es zu ändern zerschießt es mir meinen Eintrag.

    Hoffe das ist verständlich...
     
  5. Tja_was

    Tja_was Grünschnabel

    @Yaslaw
    Vielen vielen Dank! Das probiere ich jetzt gleich mal aus.
    Aber, was kann ich denn tun wenn ich den Eintrag nicht als Datum ausgeben bzw. ändern kann?
     
  6. Yaslaw

    Yaslaw n/a Moderator

    Steht doch. STR_TO_DATE() macht aus einem String ein Datum. Ohne Datum kannst du keine Datumsrechnungen durchführen.
     
  7. Tja_was

    Tja_was Grünschnabel

    Hallo Yaslaw,

    vielen Dank für Deine Geduld. Ich hab jetzt eine Menge probiert, aber egal wie, ich erhalte immer:

    Fatal error: Call to a member function format() on null ...

    Der Fehler verweist auf:

    PHP:
    1. $dateString = $suchdatum->format("Y-m-d");
    Irgendwie funktioniert was mit der Formatierung nicht - aber was? Hast Du eine Idee?

    Vielen Dank und viele Grüße
     
  8. Yaslaw

    Yaslaw n/a Moderator

    Hm. Bei mir funktioniert der Test: Test bei phpfiddle
    Code (PHP):
    1. <?php
    2. $suchdatum = new DateTime("-100 days");
    3. echo $suchdatum->format("Y-m-d");
    4. ?>
    Die Fehlermeldung besagt eigentlich, das $suchdatum nicht definiert wurde. In einem alten Post hast du des definiert. Aber wie es im aktuellen Code ist, sehe ich anhand deines Einzeilers nicht.
     
  9. Tja_was

    Tja_was Grünschnabel

    Ja, wer lesen kann.. Ich hab ein Semikolon vergessen.. Und dafür so vierl versucht. Tut mir leid, hätte ich meinen Code besser gelesen hätte es mir gleich auffallen müssen.

    Vielen vielen Dank. Hab Dank Dir eine Menge dazu gelernt!
     
  10. Tja_was

    Tja_was Grünschnabel

    Ich hätte bitte doch noch eine Frage:

    Meine Abfrage sieht jetzt so aus:
    PHP:
    1. $suchdatum = new DateTime("-100 days");
    2. echo $suchdatum->format("Y-m-d");
    3. $dateString = $suchdatum->format("Y-m-d");
    4. $sql = "CREATE VIEW auswahl_view AS
    5. SELECT meta_value, meta_key, post_id FROM wb16_postmeta
    6. WHERE
    7.       meta_key='name' OR meta_key='kontakt' OR meta_key='start-datum' OR meta_value='conditioner'";
    8. $result = mysql_query($sql) or die("Anfrage fehlgeschlagen: " . mysql_error());
    9. $query = "
    10.   SELECT
    11.       meta_value,
    12.       post_id
    13.    FROM auswahl_view
    14.   WHERE
    15.       (meta_key='start-datum'
    16.       AND (DATEDIFF(CURDATE(), STR_TO_DATE(meta_value, '%d-%m-%Y')) = 350))";
    17. $result = mysql_query($query) or die("Anfrage fehlgeschlagen: " . mysql_error());
    Die Ansicht 'auswahl_view' beinhaltet schon mal die Vorauswahl. Wie schaffe ich es jetzt, dass ich nicht nur das Datum und die ID erhalte sondern auch noch Angaben wie Name und Kontakt?

    Oder ist mein Ansatz falsch? Verschachtelte Abfragen sind echt nicht so einfach.. Ich dachte auch schon an CASE oder eine IF ELSE Abfrage..
     
  11. Tja_was

    Tja_was Grünschnabel

    Durch das Erzeugen der VIEW habe ich schon eine Vorauswahl getroffen. Die Datumsabfrage klappt auch, aber mein Ergebnis sieht so aus:
    29-11-2015 2318
    29-11-2015 2324

    Ist schon die Hälfte der Miete.. Aber ich brauche noch die passenden Informationen zur ID. Gibt es da keine Möglichkeit? Leider kann man ja nicht mehr ANDs dazuschreiben.. Sonst wäre es ja einfach.. ;)

    Ich brauch nur einen Ansatz. Oder einen Schubs in die richtige Richtung. Bitte!
     
  12. Yaslaw

    Yaslaw n/a Moderator

    Jedes mal eine View erstellen -> Falscher Ansatz.

    Alles in einem. Schwer ist es nicht
    Code (SQL):
    1. SELECT DISTINCT
    2.     pm.*
    3. FROM
    4.     wb16_postmeta AS pm,
    5.     (
    6.         SELECT
    7.             post_id,
    8.             str_to_date(meta_value, '%d-%m-%Y') AS start_date
    9.         FROM wb16_postmeta
    10.         WHERE meta_key='start-datum'
    11.     ) AS sd
    12. WHERE
    13.     pm.post_id = sd.post_id
    14.     AND datediff(curdate(), sd.start_date) = 350
    Bist du sicher, dass es =350 sein muss? Also nur was genau vor 350 Tagen war?

    Ergänzt um deinen weiteren Filter der View
    Code (SQL):
    1. SELECT DISTINCT
    2.     pm.*
    3. FROM
    4.     wb16_postmeta AS pm,
    5.     (
    6.         SELECT
    7.             post_id,
    8.             str_to_date(meta_value, '%d-%m-%Y') AS start_date
    9.         FROM wb16_postmeta
    10.         WHERE meta_key='start-datum'
    11.     ) AS sd
    12. WHERE
    13.     pm.post_id = sd.post_id
    14.     AND datediff(curdate(), sd.start_date) < 350
    15.     AND (
    16.         pm.meta_key IN ('name','kontakt','start-datum')
    17.         OR pm.meta_value='conditioner'
    18.     )
     
  13. Tja_was

    Tja_was Grünschnabel

    Das mit dem VIEW hab ich über
    PHP:
    1. $sql = "CREATE OR REPLACE VIEW auswahl_view AS
    2. SELECT meta_value, meta_key, post_id FROM wb16_postmeta
    3. WHERE
    4.       meta_key='name' OR meta_key='kontakt' OR meta_key='start-datum' OR meta_value='conditioner'";
    gedacht zu lösen..
    Das Problem ist allerdings, dass ich eigentlich kein OR meta_value='conditioner' bräuchte sondern ein AND. Das heißt ich wollte erst eine Abfrage machen bei dem alle Datensätze die Meta_value='conditioner' haben aufgelistet werden und danach nach Datum gefiltert werden. Funktioniert nur leider nicht. Das Script soll dann 1 x täglich als cronjob laufen..

    Ich hab das mal ausprobiert, aber jetzt funktioniert das Selektieren vom Datum nicht mehr? Er gibt mir jetzt zwar alle Informationen aber ohne Datums-Selektion.
     
  14. Yaslaw

    Yaslaw n/a Moderator

    Eine View, die erstellt man einmal und dann ist die da. Die ist Bestandteil des Programms.

    Da du nur sehr spezifische Felder auswählst, würde ich eine Kreuztabelle erstellen und diese nach dem Gruppieren mit HAVING (ist wie ein WHERE, wird aber auf das gruppierte Ergebnis angewendet) ausfiltern

    Code (SQL):
    1. SELECT
    2.     post_id,
    3.     MAX(IF(meta_key = 'name', meta_value, '')) AS name,
    4.     MAX(IF(meta_key = 'kontakt', meta_value, '')) AS kontakt,
    5.     MAX(IF(meta_key = 'start-datum', str_to_date(meta_value, '%d-%m-%Y'), '')) AS start_date,
    6.     MAX(meta_value = 'conditioner') AS is_conditioner
    7. FROM wb16_postmeta
    8. GROUP BY post_id
    9. HAVING
    10.     is_conditioner
    11.     AND datediff(curdate(), start_date) = 350
    Das ergibt dann so etwas:
    Code (Text):
    1. post_id | name  | kontakt | start_date | is_conditioner
    2. --------|-------|---------|------------|---------------
    3.       1 | meier |         | 2015-12-31 | 1
     
  15. Tja_was

    Tja_was Grünschnabel

    Kreuztabelle ist also das Zauberwort. Du bist echt ein Held!!!
    So schaut das gleich ganz anders aus. :)

    Vielen Dank!!!
     
  16. Yaslaw

    Yaslaw n/a Moderator

    Vorsicht. Es heisst zwar Kreuztabelle oder Pivottabelle. Aber es ist ein Query. Die Daten sollten nicht so gespeichert werden. Damit kannst du einfach relativ elegant die wesentlichen Werte auslesen und konvertieren.
    Hier lohnt es sich ev. die Kreuztabelle (ohne HAVING) als View zu speichern. Aber einmalig, nicht bei jedem lauf.
     
Die Seite wird geladen...
Ähnliche Themen - MYSQL Abfrageergbnis weiterverarbeiten
  1. jackie05
    Antworten:
    8
    Aufrufe:
    176
  2. Wurzelsepp_71
    Antworten:
    4
    Aufrufe:
    125
  3. phpgut
    Antworten:
    5
    Aufrufe:
    169
  4. Jungbluth
    Antworten:
    3
    Aufrufe:
    108
  5. chris4712
    Antworten:
    2
    Aufrufe:
    160