Lukas.: mysql: Nach Datumswerten gruppieren

Hi,

ich habe 2 Tabellen, deren Logdateneinträge ich ins Verhältnis setzen möchte. Die eine Tabelle loggt Zugriffe, die andere loggt (mir zu) langsame Zugriffe.

Tabelle 1 ist uralt und hat als Datumsspalte noch den guten alten Uniytimestamp. Die andere ist neuer und hat eine datetime-Spalte, die so speichert: 2016-09-24 11:57:01

Nun möchte ich je Tag die Summe der Logeinträge der Tabelle1 und die Summe der Logeinträge der Tabelle2 haben.

Wie gruppiere ich in beiden Fällen?

Lukas

  1. Tach!

    Nun möchte ich je Tag die Summe der Logeinträge der Tabelle1 und die Summe der Logeinträge der Tabelle2 haben.

    Wie gruppiere ich in beiden Fällen?

    In beiden Fällen gleich, über den Datumsanteil des Timestamps oder Datetime. Den zu ermitteln gibt es entsprechende Datums- und Zeit-Funktionen.

    dedlfix.

    1. In beiden Fällen gleich, über den Datumsanteil des Timestamps oder Datetime. Den zu ermitteln gibt es entsprechende Datums- und Zeit-Funktionen.

      Hi dedlfix.

      FROM_UNIXTIME(Timestamp, '%Y%|%m|%d') habe ich gefunden, aber ich finde den anderen Weg nicht.

      Lukas

      1. Tach!

        FROM_UNIXTIME(Timestamp, '%Y%|%m|%d') habe ich gefunden, aber ich finde den anderen Weg nicht.

        Den Datumsanteil ermittelt man mit der Funktion DATE().

        dedlfix.

        1. Den Datumsanteil ermittelt man mit der Funktion DATE().

          Hi dedlfix,

          dank Dir. So gelingts mir jetzt, beide Tabellen tageweise anzahlmäßig zu gruppieren.

          Leider haben die Tabellen außer dem gemeinsamen Tag nichts gemeinsam.

          Nach welcher Strategie setzt man nun sinnigerweise die jeweiligen Tageszahlen ins Verhältnis? Und klar, ich meine nicht, dass man eins durchs andere teilt. Ich meine, geht man da iterativ die Tage durch (wäre undramatisch, ich brauch nur die letzten 10) oder gibt es auch noch einen "pfiffigeren" Ansatz?

          Lukas

          1. Tach!

            [...] oder gibt es auch noch einen "pfiffigeren" Ansatz?

            Ich kann aus deiner Beschreibung nicht erkennen, welches konkrete Problem du mit welchen Daten hast.

            dedlfix.

            1. Tach!

              [...] oder gibt es auch noch einen "pfiffigeren" Ansatz?

              Ich kann aus deiner Beschreibung nicht erkennen, welches konkrete Problem du mit welchen Daten hast.

              Hi dedlfix,

              ok.

              Ich habe 2 gruppierte Ergebnismengen.

              Die kann ich iterativ (nennt man doch so, per Schleife, oder?) miteinander vergleichen und dann jeweils taggenau ins Verhältnis setzen.

              Vielleicht kann man sich das aber auch sparen, weils es ja etwas "intelligenteres" (woran ich nicht gedacht hatte) gibt.

              Besser kann ichs nicht erklären.

              Schönen Abend, gute N8 :-)

              Lukas

              1. Tach!

                Besser kann ichs nicht erklären.

                Doch, du könntest ein paar Beispieldaten geben und erklären, was wie zusammengehört und was nicht und wie das Ergebnis aussehen soll.

                dedlfix.

                1. Tach!

                  Besser kann ichs nicht erklären.

                  Doch, du könntest ein paar Beispieldaten geben und erklären, was wie zusammengehört und was nicht und wie das Ergebnis aussehen soll.

                  Hi dedlfix,

                  nicht bös sein, aber irgendwie habe ich den Eindruck, ich drücke mich heut' nicht gut genug aus.

                  Was nicht weiter schlimm ist, es hat schon so oft besser geklappt, Du hast mir schon so oft geholfen.

                  Dafür nochmal vielen, vielen Dank.

                  Vielleciht gehts beim nächsten mal wieder besser. Was diesen Thread angeht, glaube ich, komme ich ab hier alleine klar.

                  Danke nochmal für "date",

                  Lukas

                  1. Ich liefere mal nach, was für eine forenfreundliche Fragestellung nötig gewesen wäre. Da ich Gedanken nur deutlich lesen kann, wenn ich Dir direkt in die Augen schaue, bin ich auf die undeutlichen Emanationen zwischen deinen geschriebenen Zeilen angewiesen und könnte eventuell nicht ganz richtig liegen.

                    Du hast zwei Tabellen mit Timestamps und Werten. Die Timestamps bringst Du irgendwie auf Tage herunter und zählst, wieviele Werte es in den Tabellen pro Tag gibt. Bis dahin bist Du klar gekommen. Deshalb abstrahiere ich das Problem der Datumsgewinnung und nehme an, dass die Tabellen eine einfache und kompatible Datumsspalte hätten, so dass die Gruppierung pro Log-Tabelle so vereinfacht werden kann.

                    SELECT datum, COUNT(*) AS zeilen FROM logTab1 GROUP BY datum
                    

                    Ich habe mir zwei Testtabellen logTab1 und logTab2 gemacht. Wenn ich den Select drüberlaufen lasse, liefern sie mir

                    datum   zeilen
                       1       2
                       2       3
                       3       4
                       4       2
                       5       1 
                    
                    datum   zeilen
                       1       1
                       2       2
                       4       1
                    

                    Wenn ich Dich richtig verstehe, willst Du eine Quote haben, wieviele "Langsame" Einträge (in logTab2) es im Vergleich zu allen Einträgen des Tages (in logTab1) gibt, d.h. Du erwartest etwas in dieser Art

                    datum    quote
                       1     0,5
                       2     0,67
                       3       0
                       4     0,5
                       5       0
                    

                    Lösung ist ein LEFT OUTER JOIN der beiden Gruppierergebnisse. Die FROM Klausel akzeptiert nämlich nicht nur Tabellennamen, sondern auch SELECT-Abfragen (weil die auch nur Tabellen liefern). Ein kleines Problem sind die Tage, wo Du keine langsamen Requests hattest, die fehlen in der logTab2-Auswertung und ein LEFT JOIN erzeugt dann NULL als Wert für diese Spalten. Dafür gibt's die Funktion COALESCE, der übergibst beliebig viele Parameter und zurück kommt der erste, der nicht NULL ist. Den CAST(... as float) habe ich hinzugefügt, weil sonst eine INTEGER-Division stattfindet und deren Ergebnis wäre in deinem Fall immer 0.

                    SELECT x.datum, x.zeilen, y.datum, y.zeilen, CAST(COALESCE(y.zeilen, 0) AS FLOAT)/ x.zeilen AS Quote
                    FROM (SELECT datum, COUNT(*) AS zeilen FROM logTab1 GROUP BY datum) x LEFT JOIN
                         (SELECT datum, COUNT(*) AS zeilen FROM logTab2 GROUP BY datum) y ON x.datum = y.datum
                    

                    Die Query ist etwas breiter als Du es brauchst, aber so siehst Du auch die Zwischenergebnisse. Das Ergebnis sieht so aus:

                    datum    zeilen    datum    zeilen    quote
                       1        2         1        1        0,5
                       2        3         2        2        0,67
                       3        4       NULL     NULL       0
                       4        2         4        1        0,5
                       5        1       NULL     NULL       0
                    

                    Die Anwendung dieses Vorschlages auf das Problem sei dem Leser als Übung überlassen ;-)

                    Rolf

                    1. Hallo Rolf,

                      erstmal danke für Deine Hilfe und Mühe. Genau an so eine "pfiffige" Lösung hatte ich gedacht (auch, wenn ich sie noch nicht so ganz verstehe, aber daran kann man ja wachsen). Und Du hast auch genau beschrieben, was ich habe und was ich gerne hätte.

                      Du hast zwei Tabellen mit Timestamps und Werten. Die Timestamps bringst Du irgendwie auf Tage herunter und zählst, wieviele Werte es in den Tabellen pro Tag gibt. Bis dahin bist Du klar gekommen. Deshalb abstrahiere ich das Problem der Datumsgewinnung und nehme an, dass die Tabellen eine einfache und kompatible Datumsspalte hätten, so dass die Gruppierung pro Log-Tabelle so vereinfacht werden kann.

                      SELECT datum, COUNT(*) AS zeilen FROM logTab1 GROUP BY datum
                      

                      Ja, genau. Ich habe jetzt auch mal 2 Testtabellen angelegt.

                      CREATE TABLE IF NOT EXISTS `access` (
                      `ID` int(3) NOT NULL,
                        `last` int(20) NOT NULL DEFAULT '0'
                      ) ENGINE=MyISAM;
                      
                      
                      INSERT INTO `access` (`ID`, `last`) VALUES
                      (1, 1474968700),
                      (2, 1474968700),
                      (3, 1474882300),
                      (4, 1474882300),
                      (5, 1474882300),
                      (6, 1474882300),
                      (7, 1474795900),
                      (8, 1474795900),
                      (9, 1474795900),
                      (10, 1474795900),
                      (11, 1474795900),
                      (12, 1474709500),
                      (13, 1474709500),
                      (14, 1474709500),
                      (15, 1474709500),
                      (16, 1474709500),
                      (17, 1474709500);
                      
                      
                      
                      CREATE TABLE IF NOT EXISTS `slow` (
                      `ID` int(6) NOT NULL,
                        `Erstelldatum` datetime NOT NULL
                      ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
                      
                      
                      INSERT INTO `slow` (`ID`, `Erstelldatum`) VALUES
                      (1, '2016-09-24 11:54:53'),
                      (2, '2016-09-24 11:57:01'),
                      (3, '2016-09-24 11:57:57'),
                      (4, '2016-09-25 11:57:57'),
                      (5, '2016-09-25 11:57:01'),
                      (6, '2016-09-26 11:57:01');
                      
                      

                      Ich habe mir zwei Testtabellen logTab1 und logTab2 gemacht. Wenn ich den Select drüberlaufen lasse, liefern sie mir

                      Ja, auch meine liefern gute Einzelwerte:

                      SELECT FROM_UNIXTIME(last, '%Y%-%m-%d') , count( * ) AS Anzahl
                      FROM `access`
                      GROUP BY FROM_UNIXTIME(last, '%Y%-%m-%d')
                      ORDER BY Anzahl DESC
                      

                      ergibt:

                      2016-09-24 	6
                      2016-09-25 	5
                      2016-09-26 	4
                      2016-09-27 	2
                      

                      Und folgende Abfrage:

                      SELECT date( `Erstelldatum` ) , count( * )
                      FROM `slow`
                      GROUP BY date( `Erstelldatum` )
                      

                      ergibt:

                      2016-09-24 	3
                      2016-09-25 	2
                      2016-09-26 	1
                      

                      Lösung ist ein LEFT OUTER JOIN der beiden Gruppierergebnisse. Die FROM Klausel akzeptiert nämlich nicht nur Tabellennamen, sondern auch SELECT-Abfragen (weil die auch nur Tabellen liefern). Ein kleines Problem sind die Tage, wo Du keine langsamen Requests hattest, die fehlen in der logTab2-Auswertung und ein LEFT JOIN erzeugt dann NULL als Wert für diese Spalten. Dafür gibt's die Funktion COALESCE, der übergibst beliebig viele Parameter und zurück kommt der erste, der nicht NULL ist. Den CAST(... as float) habe ich hinzugefügt, weil sonst eine INTEGER-Division stattfindet und deren Ergebnis wäre in deinem Fall immer 0.

                      An dieser Erklärung knabbere ich gerade...

                      SELECT x.datum, x.zeilen, y.datum, y.zeilen, CAST(COALESCE(y.zeilen, 0) AS FLOAT)/ x.zeilen AS Quote
                      FROM (SELECT datum, COUNT(*) AS zeilen FROM logTab1 GROUP BY datum) x LEFT JOIN
                           (SELECT datum, COUNT(*) AS zeilen FROM logTab2 GROUP BY datum) y ON x.datum = y.datum
                      

                      Die Query ist etwas breiter als Du es brauchst, aber so siehst Du auch die Zwischenergebnisse. Das Ergebnis sieht so aus:

                      datum    zeilen    datum    zeilen    quote
                         1        2         1        1        0,5
                         2        3         2        2        0,67
                         3        4       NULL     NULL       0
                         4        2         4        1        0,5
                         5        1       NULL     NULL       0
                      

                      Wäre genau das Ergebnis, welches ich erzeugen will...

                      Die Anwendung dieses Vorschlages auf das Problem sei dem Leser als Übung überlassen ;-)

                      Bin schon dabei. Aber bisher nur mit einem MySQL-Error.

                      SELECT x.datum, x.zeilen, y.datum, y.zeilen, CAST(COALESCE(y.zeilen, 0) AS FLOAT)/ x.zeilen AS Quote
                      FROM (SELECT FROM_UNIXTIME(last, '%Y%-%m-%d'), COUNT(*) AS zeilen FROM access GROUP BY FROM_UNIXTIME(last, '%Y%-%m-%d')) x LEFT JOIN
                           (SELECT date( `Erstelldatum` ), COUNT(*) AS zeilen FROM slow GROUP BY date( `Erstelldatum` )) y ON x.FROM_UNIXTIME(last, '%Y%-%m-%d') = y.date( `Erstelldatum` )
                      
                      

                      ergibt leider bei mir nicht obige Tabelle, sondern:

                      #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FLOAT)/ x.zeilen AS Quote
                      FROM (SELECT FROM_UNIXTIME(last, '%Y%-%m-%d'), COUNT(*' at line 1 
                      

                      Da ich den oben eingesetzten Begriff "CAST(COALESCE(y.zeilen, 0) AS FLOAT)" nicht wirklich verstehe, kann ich auch die Fehlermeldung nicht verstehen.

                      Lukas

                      1. Hallo

                        SELECT x.datum, x.zeilen, y.datum, y.zeilen, CAST(COALESCE(y.zeilen, 0) AS FLOAT)/ x.zeilen AS Quote
                        FROM (SELECT FROM_UNIXTIME(last, '%Y%-%m-%d'), COUNT(*) AS zeilen FROM access GROUP BY FROM_UNIXTIME(last, '%Y%-%m-%d')) x LEFT JOIN
                             (SELECT date( `Erstelldatum` ), COUNT(*) AS zeilen FROM slow GROUP BY date( `Erstelldatum` )) y ON x.FROM_UNIXTIME(last, '%Y%-%m-%d') = y.date( `Erstelldatum` )
                        
                        

                        ergibt leider bei mir nicht obige Tabelle, sondern:

                        #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FLOAT)/ x.zeilen AS Quote
                        FROM (SELECT FROM_UNIXTIME(last, '%Y%-%m-%d'), COUNT(*' at line 1 
                        

                        Da ich den oben eingesetzten Begriff "CAST(COALESCE(y.zeilen, 0) AS FLOAT)" nicht wirklich verstehe, kann ich auch die Fehlermeldung nicht verstehen.

                        Mit COALESCE werden die Werte einer Spalte durchgegangen und der erste Wert, der nicht NULL ist, ausgegeben. Mit CAST erfolgt eine Typumwandlung, hier mit AS FLOAT als Fließkommazahl. Wenn ich die Auflistung der für CONVERT möglichen Datentypen, die auch für CAST gilt, richtig interpretiere, gibt es keinen zulässigen Datentypen FLOAT, dafür aber den Typ DECIMAL.

                        SELECT
                          x.datum,
                          x.zeilen,
                          y.datum,
                          y.zeilen,
                          CAST(COALESCE(y.zeilen, 0) AS DECIMAL([Gesamtanzahl der Stellen], [Anzahl der Nachkommastellen])) / x.zeilen AS Quote
                        FROM

                        Tschö, Auge

                        --
                        Wo wir Mängel selbst aufdecken, kann sich kein Gegner einnisten.
                        Wolfgang Schneidewind *prust*
                        1. Hups? Float ist eine MS SQL Erweiterung? Sorry. Hätte mir klar sein müssen.

                          Rolf

                          PS: Bitte vermeidet Full Quotes. Das Forum belegt das Antwortfenster zwar damit vor, aber das ist nur ein Bergwerk für die benötigten Zitate. Wer sich über die Historie der Konversation informieren will, kann jederzeit hochscrollen.

                          Rolf

                          1. Hallo

                            Hups? Float ist eine MS SQL Erweiterung? Sorry. Hätte mir klar sein müssen.

                            Nee, nee. FLOAT gibt's auch in MySQL, aber, wenn ich der Doku vertrauen kann [1], eben nicht für CONVERT und CAST.

                            PS: Bitte vermeidet Full Quotes. Das Forum belegt das Antwortfenster zwar damit vor, aber das ist nur ein Bergwerk für die benötigten Zitate. Wer sich über die Historie der Konversation informieren will, kann jederzeit hochscrollen.

                            Mit wem sprichst du? Im Übrigen ist hier (bei mir) nix mit hochscrollen.

                            Tschö, Auge

                            --
                            Wo wir Mängel selbst aufdecken, kann sich kein Gegner einnisten.
                            Wolfgang Schneidewind *prust*

                            1. Ich habe am Punkt erlaubte Datentypen ja auf die MySQL 5.5-Doku verlinkt, die nicht die der aktuellen Version ist. ↩︎

                            1. Ok, ich habe standardmäßig die "Nested" Ansicht eingeschaltet, du offenbar die "Thread" Ansicht. Kann man in den Einstellungen umschalten. Aber für Thread-Ansicht gips unten den Thread-Navigator... Na egal, ich hatte die Ausführungen von Lukas, weil sie meinem Text so ähnlich sahen, für ein Fullquote gehalten und blindlings überflogen :)

                              Dass CAST(... as float) in MySQL nicht geht, finde ich ja nun sehr merkwürdig. Ist doch ein Typ, genau wie Decimal. Aber gut. Man kann ja statt dessen auch COALESCE(y.zeilen, 0)*1.0 / x.zeilen AS Quote schreiben, das konvertiert auch in Fließkomma. Und dann sollte die Abfrage hoffentlich ticken.

                              Rolf

                              1. Hi Rolf,

                                Na egal, ich hatte die Ausführungen von Lukas, weil sie meinem Text so ähnlich sahen, für ein

                                Fullquote gehalten und blindlings überflogen :)

                                Blindlinks überflogen? Oh. Dabei hatte ich mir so Mühe gegeben ;) Und ein Fullquote wars auch nicht.

                                Und dann sollte die Abfrage hoffentlich ticken.

                                Naja, sollte... tut sie aber nicht bei mir...

                                Lukas

                        2. CAST(COALESCE(y.zeilen, 0) AS DECIMAL([Gesamtanzahl der Stellen], [Anzahl der Nachkommastellen])) / x.zeilen AS Quote

                          Hi Auge,

                          stimmt völlig, die fehlermeldung ist auch weg. Dafür wimmelts von anderen Fehlermeldungen, ich schaffs irgendwie nicht, die Query umzusetzen.

                          Es hapert schon dabei, die beiden gruppierten Tabellen zu joinen:

                          (SELECT FROM_UNIXTIME(last, '%Y%-%m-%d') AS Datum1, COUNT(*) AS zeilen FROM access GROUP BY Datum1) AS x 
                          LEFT JOIN
                          (SELECT date( Erstelldatum ) AS Datum2, COUNT(*) AS zeilen FROM slow GROUP BY Datum2) AS y 
                          ON 
                          x.Datum1 = y.Datum2
                          

                          ergibt:

                          #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS x
                          LEFT JOIN
                          (SELECT date( Erstelldatum ) AS Datum2, COUNT(*) AS zeilen FROM ' at line 1 
                          

                          und ich weiß nicht, warum...

                          Lukas

                          1. Hallo Lukas,

                            so, jetzt habe ich mir Zugang zu einer MySQL DB verschafft und das mal ausprobiert; es funktioniert grundsätzlich.

                            Dumme Frage: Du hast deinen JOIN als Teil einer FROM Klausel notiert? Wenn nicht: ok, Joins müssen immer in einem FROM stehen. Wenn doch: ersetze mal den SELECT Teil durch SELECT *, um sicher zu sein, dass nicht irgendein Folgefehler von dort den JOIN grillt. Oder zeig mal die vollständige Query.

                            Übrigens hab ich bemerkt, dass man in MySQL gar nicht casten muss, der produziert aus der Integer-Division ein Decimal-Result. MS SQL macht ein Integer-Result draus.

                            Rolf

                            1. Hi Rolf,

                              Dumme Frage: Du hast deinen JOIN als Teil einer FROM Klausel notiert? Wenn nicht: ok, Joins müssen immer in einem FROM stehen.

                              Oh. Ist das so? Du meinst aber doch dann sicher JOINS aus ergebnismengen, oder? Weils JOINS ohne FROM gibts ja ansosnten zu genüge. Aber du hast recht... ein SELECT * FROM davor und ich erhalte ein Ergebnis :)

                              Jetzt nur noch das * ersetzen... ich schau mal, was da noch für Problemchen auf mich warten.

                              Lukas

                              1. Hi Rolf,

                                Jetzt nur noch das * ersetzen... ich schau mal, was da noch für Problemchen auf mich warten.

                                Gar keine. Geht alles schnell und problemlos durch.

                                Eine Frage noch: Weil die "echte" access-datei schon ziemlich große ist (> 2 Mio. Einträge): Wenn ich nur die letzten 14 Tage betrachten möchte, wo setze ich dann am besten m it meinem LIMIT an?

                                Lukas

                                1. Hallo

                                  Eine Frage noch: Weil die "echte" access-datei schon ziemlich große ist (> 2 Mio. Einträge): Wenn ich nur die letzten 14 Tage betrachten möchte, wo setze ich dann am besten m it meinem LIMIT an?

                                  Am Zeitraum von konkret 14 Tagen? 14 Tage zurückzurechnen und in der Where-Klausel eine BETWEEN-Bedingung auf die Datumsspalte einzubauen, sollte selbst mit älteren Access-Versionen kein Problem sein. Allerdings frage ich mich, wo hier MySQL ins Spiel kommt. Wenn du aber von Access aus einen MySQL-Server ansprechen solltest, sind wiederum Beschränkungen in Access egal.

                                  Tschö, Auge

                                  --
                                  Wo wir Mängel selbst aufdecken, kann sich kein Gegner einnisten.
                                  Wolfgang Schneidewind *prust*
                                2. Eine Frage noch: Weil die "echte" access-datei schon ziemlich große ist (> 2 Mio. Einträge): Wenn ich nur die letzten 14 Tage betrachten möchte, wo setze ich dann am besten m it meinem LIMIT an?

                                  Arghs, Käse. LIMIT ist natürlich in diesem Fall eh Unfug. Hierzu muß ich ja die Datumsfunktionen von MySQL bemühen...

                                  Lukas

                                  1. Arghs, Käse. LIMIT ist natürlich in diesem Fall eh Unfug. Hierzu muß ich ja die Datumsfunktionen von MySQL bemühen...

                                    Danke für Eure Hilfe, so siehts ganz gut aus, finde ich:

                                    SELECT
                                      x.datum,
                                      x.zeilen,
                                      y.datum,
                                      y.zeilen,
                                      CAST(COALESCE(y.zeilen, 0) AS DECIMAL(5, 2)) / x.zeilen AS Quote
                                    FROM
                                    
                                    (SELECT FROM_UNIXTIME(last, '%Y%-%m-%d') AS datum, COUNT(*) AS zeilen FROM access WHERE DATEDIFF(CURDATE(),FROM_UNIXTIME(last, '%Y%-%m-%d')) < 14 GROUP BY datum) AS x 
                                    LEFT JOIN
                                    (SELECT date( Erstelldatum ) AS datum, COUNT(*) AS zeilen FROM slow WHERE DATEDIFF(CURDATE(),date( Erstelldatum )) < 14 GROUP BY datum) AS y 
                                    ON 
                                    x.datum = y.datum
                                    

                                    Lukas

                                    1. Schön :)

                                      Ob der DATEDIFF bei der genannten Table-Größe performant ist, müsste man aber nochmal überlegen. Er muss ja in der access-Tabelle für JEDEN Datensatz der Table die FROM_UNIXTIME(last) Konvertierung und den DateDiff durchführen. Bei mehreren Millionen Zeilen ist das nicht unbedingt fix. Und ob er bei Einsatz einer solchen Funktion einen möglicherweise vorhandenen Index auf die last Spalte nutzen kann, weiß ich auch nicht. Dazu müsstest Du einen EXPLAIN auf die Query machen. Ich guck mir das im MySQL selbst noch mal an.

                                      Ich weiß nicht, wie du das SQL aufrufst. Wenn es aus PHP oder einer anderen Programmiersprache heraus erfolgt, solltest Du Dir den Unix-Timestamp für "14 Tage vor heute um Mitternacht" dort einmalig berechnen und diesen Wert direkt mit der last-Spalte vergleichen.

                                      Wenn die slow-Tabelle relativ klein ist, musst Du da wohl nichts machen. Du kannst aber auch da das Grenzdatum vorberechnen und in die Query einsetzen.

                                      Ob es für die Laufzeit der Query etwas ausmachst, müsstest Du testen. Das kannst Du ohne zu programmieren, indem Du statt des DATEDIFF eine fixe Abfrage last >= 1473717600 (das ist der 13.9.) einsetzt. In der slow-Tabelle müsstest Du wohl Erstelldatum >= '2016-09-13' schreiben.

                                      Rolf

                                      1. Nachtrag:

                                        Der DATEDIFF führt dazu, dass ein Index, der auf last liegt, nicht verwendet wird (zumindest bei meinen Tests gerade nicht), und das kostet bei der Tabellengröße viel Zeit. Je nach Häufigkeit deiner Abfrage könnte das vorteilhaft sein. Nachteil eines Index ist natürlich, dass er bei jedem Schreibzugriff aktualisiert werden muss; hier musst Du abwägen. Wenn das Schreiben in die Log-Tabelle zeitkritisch ist, muss man eventuell die längere Laufzeit durch den Tablescan bei der Auswertung in Kauf nehmen.

                                        Die Formulierung
                                        WHERE last >= UNIX_TIMESTAMP(DATE_ADD(CURDATE(), INTERVAL -14 DAY))
                                        verwendet dagegen einen vorhandenen Index.

                                        Die DATE_ADD Variante kannst Du auch in der slow-Tabelle benutzen.

                                        Rolf

                                        1. Hi Rolf,

                                          gute Hinweise! Am besten gefält mir aber Deine Idee, php-seitig den Timestamp auszurechnen und das dann in der Query zu verwenden. So werde ich es machen.

                                          Gruß, Lukas

                              2. Hallo

                                Aber du hast recht... ein SELECT * FROM davor und ich erhalte ein Ergebnis :)

                                Als grundsätzlicher, nicht von mir ge- und erfundener, also nur zum wiederholten Male wiederholter, und nicht nur an dich gerichteter Tip:

                                Prüfe jeden Select einzeln darauf, ob die erwarteten Ergebnisse zurückkommen. Das gilt insbesondere für mehrfache Joins und Subselects. Wenn z.B. ein Select mit Subselects in der Where-Klausel oder wie bei dir im From-Teil [1] nicht am Stück funktioniert, ohne, dass die einzelnen Teile im Vorfeld erfolgreich getestet wurden, beginnt das auseinanderreißen und im Nebel der Einzelteile herumstochern. Das kann man sich mit den Prüfungen ein Stück weit ersparen.

                                Jetzt nur noch das * ersetzen... ich schau mal, was da noch für Problemchen auf mich warten.

                                Toi, toi, toi.

                                Tschö, Auge

                                --
                                Wo wir Mängel selbst aufdecken, kann sich kein Gegner einnisten.
                                Wolfgang Schneidewind *prust*

                                1. Was ich selbst noch nicht brauchte und somit nicht aus eigener Arbeit kenne. ↩︎

                                1. Hi Auge,

                                  Prüfe jeden Select einzeln darauf, ob die erwarteten Ergebnisse zurückkommen.

                                  Jaja. Genau so war ich vorgegangen. Beide Einzelselects prüfen--- ging. Dann den Join der Einzelselects prüfen--- ging nicht. Aber wie gesagt, ich wußte nicht, dass JOINS aus ergebnismengen ohne SELECT nicht funktionieren.

                                  Lukas