Hallo zusammen,
folgendes, ich habe eine SQL Tabelle mit vielen Datensätze. Jeder Datensatz enthält im Feld datum das Datum wann der Datensatz eingetragen wurde.
Feld datum ist int(20) und enthält einen time() Eintrag.
Jetzt möchte ich per „SELECT DISTINCT datum FROM“ nur die Monate aus dem Feld datum ausgeben werden.
Bekomme ich das über SELECT Abfrage hin, oder muss ich in der Tabelle ein weiteres Feld einfügen und nur die Monate eintragen lassen um anschließend dann darüber Filtern zu können?
Ich sage schon mal Danke Oliver
MySQL SELECT DISTINCT .... Vorfilterung?
-
-
Falscher anstazt. Ich weiss zwar nicht genau ob es sowas wie die date-funtkion auch in MySQL gibt, ich denke aber schon.
Lass doch einfach nach datum (bzw. deinem Timestamp) vorsortierne und pick dir den Monat per PHP raus - ist sogar performanter. -
Danke Tobse,
wenn ich hier keine Elegante Lösung erhalte werde, werde ich irgend etwas in diese Richtung programmieren.
Grüße Oliver
-
ist sogar performanter.
Das ist Quatsch! Wieso soll ich mit PHP sortieren und Filtern, wenn ich das schon mit MySQL erledigen kann. Es wäre einfacher, wenn man in der Tabellenspalte Datum auch ein Datum speichert, also vom Type date. Dafür gibt's das nämlich -
Es wäre einfacher, wenn man in der Tabellenspalte Datum auch ein Datum speichert, also vom Type date. Dafür gibt's das nämlich
So ist es aber nicht. Wenn er die MySQL DATE funktion verwendet, muss MySQL für JEDEN Datensatz, also ganz egal, ob er hinterher im resultat ersccheint, die Funktion ausführen. Wenn PHP die Funktion allerdings nur auf die relevaten anwendet, ist das natürlich performanter. -
Und bei einem Timestamp wirst du kein Distinct sinnvoll einsetzen können. Mit anderen Worten, du musst alle Datensätze aus der DB auslesen und dann mit PHP filtern. Und das soll performanter sein? Im Leben nicht!
Die Spalte datum von timestamp nach date konvertieren ist ja keine gigantischer Akt. -
So, mein lieber Tobse! Habe gerade etwas Zeit gehabt und mal getestet:
Select distinct month(datum) as monate from tabelle
Da braucht phpMyAdmin bei einer Tabelle mit 500.000 Datensätzen gerade mal 0.25 Sekunden. Mach das mal mit deiner Methode.
-
Für Datums-Felder nimmt man auch die Datums-Feldtypen von MySQL, dafür gibt es die. Ein INT ist eine schlechte Idee, warum zeigt sich hier mal wieder. Du brauchst im Query jedesmal eine Funktion mehr wenn du Datums-Berechnungen/-Formatierungen in der Abfrage durchführen willst. Und das ist performanter als PHP rödeln zu lassen.
-
Hallo zusammen,
vielen Dank für die tolle Diskussion und Antworten!!!
Warum ich INT Verwende, weis ich nicht genau habe das irgendwo mal übernommen. Auch hier danke für den Tipp, ich werde in Zukunft auf „Datum“ gehen.
@SinnlosS : Genau solche Schreibweise habe ich gesucht.
Vielen Dank euch allen, Grüsse Oliver -
So, mein lieber Tobse! Habe gerade etwas Zeit gehabt und mal getestet:
Select distinct month(datum) as monate from tabelle
Da braucht phpMyAdmin bei einer Tabelle mit 500.000 Datensätzen gerade mal 0.25 Sekunden. Mach das mal mit deiner Methode.
Du vergisst, dass PHPMyAdmin aufgrund von darstellungsplätzen ein LIMIT 0, 30 (oder eben bezüglich der Seite) benitzt, weshalb MySQL 0,25 Sekunden für 30 Datensätze gebraucht hat.
EDIT:
Tabelle "timetable":PHP
Alles anzeigen<?php $db=new mysqli(...); set_time_limit(0); $sql="SELECT DISTINCT MONTH(time) FROM timetable"; $time=microtime(); if (!$db->query($sql)) { echo $db->error; exit(); } $time=microtime()-$time; echo $time."<br>"; $sql="SELECT DISTINCT time FROM timetable"; $time=microtime(); if ($erg=$db->query($sql)) { while ($res=$erg->fetch_array()) { $foo=date("m-Y", $res['time']); } } $time=microtime()-$time; $erg->close(); echo $time; $db->close(); ?>
Ausgabe: -
Setz doch mal bitte bei microtime den Parameter auf true, dein Ergebnis sagt exakt gar nix aus in der Form.
-
Immernoch schneller.
PHP
Alles anzeigen<?php $db=new mysqli(...); set_time_limit(0); $sql="SELECT DISTINCT MONTH(time) FROM timetable"; $time=microtime(true); if (!$db->query($sql)) { echo $db->error; exit(); } $time=microtime(true)-$time; echo $time."<br>"; $sql="SELECT DISTINCT time FROM timetable"; $time=microtime(true); if ($erg=$db->query($sql)) { while ($res=$erg->fetch_array()) { $foo=date("m-Y", $res['time']); } } $time=microtime(true)-$time; $erg->close(); echo $time; $db->close(); ?>
Code
Alles anzeigen0.18918585777283 0.17720413208008 0.21651482582092 0.17818307876587 0.22041511535645 0.17874884605408 0.18550992012024 0.18051195144653 0.25362706184387 0.18164610862732
Für mich ist das eindeutig. Bei 500.000 Datensätzen wäre der Unterschied noch deutlicher. -
Immernoch schneller.
Für mich ist das eindeutig. Bei 500.000 Datensätzen wäre der Unterschied noch deutlicher.
Und das ist immer noch Quatsch! Bei 500.000 Datensätzen hast du aller Wahrscheinlichkeit nach auch 500.000 unterschiedliche Timestamps. Und dann geht dein Script völlig in die Knie.Und zu phpMyAdmin und deiner Aussage mit Limit 0, 30. Meines Wissens nach gibt es nur 12 Monate.
-
Immernoch schneller.
PHP
Alles anzeigen<?php $db=new mysqli(...); set_time_limit(0); $sql="SELECT DISTINCT MONTH(time) FROM timetable"; $time=microtime(true); if (!$db->query($sql)) { echo $db->error; exit(); } $time=microtime(true)-$time; echo $time."<br>"; $sql="SELECT DISTINCT time FROM timetable"; $time=microtime(true); if ($erg=$db->query($sql)) { while ($res=$erg->fetch_array()) { $foo=date("m-Y", $res['time']); } } $time=microtime(true)-$time; $erg->close(); echo $time; $db->close(); ?>
Code
Alles anzeigen0.18918585777283 0.17720413208008 0.21651482582092 0.17818307876587 0.22041511535645 0.17874884605408 0.18550992012024 0.18051195144653 0.25362706184387 0.18164610862732
Für mich ist das eindeutig. Bei 500.000 Datensätzen wäre der Unterschied noch deutlicher.Wunderbar, und jetzt nimm bitte mal kein INT für das Datum, sondern DATE.
Auf eine Tabelle mit ~650.000 Datensätzen:
PHP
Alles anzeigen<?php require_once "dbconnect.php"; $sql="SELECT DISTINCT DATE_FORMAT(`datum`,'%Y-%m') FROM `sn_info`"; $time=microtime(true); for($i=0;$i<1000;$i++) { if (!$db->query($sql)) { echo $db->error; exit(); } } $time=microtime(true)-$time; echo $time."<br>"; $sql="SELECT DISTINCT `datum` FROM `sn_info`"; $time=microtime(true); for($i=0;$i<1000;$i++) { if ($erg=$db->query($sql)) { while ($res=$erg->fetch_array()) { $foo=date("m-Y", $res['time']); } } } $time=microtime(true)-$time; $erg->close(); echo $time; $db->close(); /* 0.73600792884827 7.1520810127258 */ ?>
DAS ist ein eindeutiges Ergebnis... -
SinnlosS
Tobse wird bestimmt in jeder Row das gleiche Datum haben, dann geht das auch zügig. -
DAS ist ein eindeutiges Ergebnis...Die Tabelle vom TS IST aber KEIN DATE! Sonst würde ich das ja nicht diskutieren.
Zitat von Unregistriert
Tobse wird bestimmt in jeder Row das gleiche Datum haben, dann geht das auch zügig.Jetzt wirts aber peinlich. Du hast verloren, zumindest was INTs angeht, sies ein. Du kannst von mier aus auch den DUMP haben unds selbst ausprobieren. Das Niveau sinkt durch deinen Post wieder in unersehliche Tiefe.
BackToTopic:
Wir haben gesehen - bei INTs ist PHP schneller, bei DATEs hat PHP absolut keine chance auch nur ansatzweise mitzuhalten. Die Tabelle vom Gast ist INT. Bei INTs braucht PHP rund 0.18 Sekunden. Bei DATEs brauch MySQL rund 0.7 Sekunden.
Dem TS rate ich daher zu INTs und PHP, er kann alelrdings auch seine Tabelle in DATE umwandeln und MySQL benutzen - völlig egal.EDIT: Ahja, der unregistrierte kann mir ja keine PM schreiben, der DUMP im anhang.
timetable.zip -
Dem TS rate ich daher zu INTs und PHP
Jau, ist gut, Tobse. Du hast recht und wir unsere Ruhe. Kopfschüttel -
Die Tabelle vom TS IST aber KEIN DATE! Sonst würde ich das ja nicht diskutieren.
Und WELCHE ROLLE soll das SPIELEN? Ein Script zum Umschreiben der Daten ist in 5 Minuten erstellt. -
Zitat
Und WELCHE ROLLE soll das SPIELEN? Ein Script zum Umschreiben der Daten ist in 5 Minuten erstellt.
Er solls sich aussuchen. -
BackToTopic:
Wir haben gesehen - bei INTs ist PHP schneller, bei DATEs hat PHP absolut keine chance auch nur ansatzweise mitzuhalten. Die Tabelle vom Gast ist INT. Bei INTs braucht PHP rund 0.18 Sekunden. Bei DATEs brauch MySQL rund 0.7 Sekunden.
Dem TS rate ich daher zu INTs und PHP, er kann alelrdings auch seine Tabelle in DATE umwandeln und MySQL benutzen - völlig egal.
Ach das fällt mir ja grad erst auf... Junge, schau dir erstmal meinen Code richtig an...
Ich habe das ganze in einer for-Schleife die 1000x durchlaufen wird, du hast einen Durchlauf. Also bitte... -