CronJob-Service
bei SELFPHP mit ...
|
+ minütlichen Aufrufen
+ eigenem Crontab Eintrag
+ unbegrenzten CronJobs
+ Statistiken
+ Beispielaufrufen
+ Control-Bereich
Führen Sie mit den CronJobs von
SELFPHP zeitgesteuert Programme
auf Ihrem Server
aus. Weitere Infos
|
:: Anbieterverzeichnis ::
Globale Branchen
Informieren Sie sich über ausgewählte Unternehmen im Anbieterverzeichnis von SELFPHP
:: Newsletter ::
Abonnieren Sie hier den kostenlosen
SELFPHP Newsletter!
|
MySQLi/PDO/(MySQL) Anfänger, Fortgeschrittene oder Experten können hier Fragen und Probleme rund um MySQLi/PDO/(MySQL) diskutieren |
14.02.2008, 17:18:50
|
Anfänger
|
|
Registriert seit: Feb 2008
Beiträge: 10
|
|
Probleme mit Aggregatfunktion
Hallo,
Ich habe folgende Tabellen:
Tabelle: file
ID, Dateiname, etc
Tabelle: log
ID, FileID, Änderungsdatum (Zeitstempel), etc
Nun möchte ich eine Ergebnismenge in der alle Dateien mit den jeweils letzten Änderungsdaten enthalten sind.
Bisher habe ich das mit einem Subselect in etwa so gelöst:
SELECT * FROM file AS f INNER JOIN log AS l ON l.FileID=f.ID WHERE l.Änderungsdatum=(SELECT MAX(ls.Änderungsdatum) FROM log AS ls WHERE ls.FileID=f.ID)
Nun sind die beiden Tabellen aber schon recht groß geworden, so dass die Abfrage ca 1s dauert.
Also probierte ich Alternativen aus, bisher hat aber leider nichts funktioniert. Da ich sowieso eine Temporäre Tabelle erstelle und diese mit der Ergebnismenge fülle, kann die Lösung auch in mehreren Schritten stattfinden - wichtig ist dabei nur die Geschwindigkeit.
Mein letzter Versuch war mit der HAVING-Klausel:
SELECT l.FileID, l.LogID, l.Änderungsdatum
FROM log AS l
GROUP BY l.FileID
HAVING MAX(l.Änderungsdatum)=l.Änderungsdatum
ORDER BY l.FileID
Diese Ergebnismenge würde ich dann in dieentsprechenden Spalten der temporären Tabelle speichern. Doch mit dieser Abfrage bekomme ich lediglich 3000 Datensätze (müssten ca 10000 sein).
Wie nutze ich die Aggregatfunktion richtig ?
Vielen Dank schon mal für die Hilfe
|
15.02.2008, 13:53:32
|
Anfänger
|
|
Registriert seit: Feb 2008
Beiträge: 10
|
|
AW: Probleme mit Aggregatfunktion
Ich versuche das Problem mal noch ein wenig einfacher darzustellen.
Tabelle: Log
LogID (primär)|FileID|ChangeDate (Zeitstempel)|etc
1|1|1202912000
2|2|1202913000
3|2|1202913500
4|2|1202917000
Nun möchte ich als Ergebnismenge zu jeder FileID die ID aus der Log-Tabelle, in der der größte Zeitstempel für diese Datei ist.
Die richtige Ergebnismenge müsste also so lauten:
FileID|LogID|ChangeDate
1|1|1202912000
2|4|1202917000
Wenn ich nun folgende Abfrage ausführe:
SELECT FileID, LogID, ChangeDate
FROM log
GROUP BY FileID
bekomme ich zu jeder FileID eine beliebige Zeile, das könnte dann so aussehen:
FileID|LogID|ChangeDate
1|1|1202912000
2|3|1202913500
Ist ja auch klar, denn ich habe mit GROUP BY ja nur gesagt das ich pro FileID nur eine einzige Zeile haben will - welche Zeile ich haben möchte habe ich aber nicht definiert.
Nächster Schritt:
SELECT FileID, LogID, ChangeDate, MAX(ChangeDate)
FROM log
GROUP BY FileID
Ergebnis:
FileID|LogID|ChangeDate|MAX(ChangeDate)
1|1|1202912000|1202912000
2|3|1202913500|1202917000
Der MAX(ChangeDate)-Wert ist also aus der Zeile die ich haben will, allerdings stimmt die LogID nicht, denn sie kommt wiederrum aus einer "zufällig" gewählten Spalte und nicht unbedingt aus der Spalte aus der MAX(ChangeDate) stammt.
Also probierte ich folgendes:
SELECT FileID, LogID, ChangeDate
FROM log
GROUP BY FileID
HAVING MAX(ChangeDate)=ChangeDate
Damit bekomme ich zwar richtige Ergebnisse, aber nicht alle Datensätze. Die Datensätze die ich bekomme sind die, die ohnehin nur eine Zeile in der Log-Tabelle enthalten (in diesem Beispiel also nur die Zeile mit der FileID 1). Die Zeitstempel in diesen Zeilen sind dann natürlich auch automatisch die MAX-Werte, da es ja nur einen Wert gibt.
Das sollte doch eigentlich kein so abwegiges Problem sein, oder ? Da müssten doch andere schon mal drauf gestossen sein...
Wie gesagt: Per Subselect (1. Post) funktioniert es, aber das läuft zu langsam bei großen Datenmengen.
Wäre wirklich dankbar für einen Schubser, da ich langsam echt verzweifle :-(
|
15.02.2008, 15:26:21
|
Anfänger
|
|
Registriert seit: Feb 2008
Beiträge: 9
|
|
AW: Probleme mit Aggregatfunktion
Hallo Plasm,
wenn die LogID das einige ist, was zu zusätzlich zum MAX(ChangeDate) selektieren willst, dann könntest Du auch MAX(LogID) in das SELECT aufnehmen. Ich gehe davon aus, dass höhste ChangeDate auch als letztes in die Datenbank geschrieben wird. Das trifft natürlich nur zu, wenn chronologisch gespeichert wird.
|
15.02.2008, 15:32:05
|
Anfänger
|
|
Registriert seit: Feb 2008
Beiträge: 10
|
|
AW: Probleme mit Aggregatfunktion
In diesem speziellen Fall brauche ich wirklich nur die LogID, aber das wird nicht immer so sein.
Im Normalfall wird chronologisch gespeichert, aber ich kann nicht 100%ig ausschliessen, dass ein ChangeDate im nachhinein per UPDATE verändert wird (aus Korrekturzwecken). D.h. ein paar wenige Einträge werden wohl dabei sein, bei denen das höhere ChangeDate der niedrigeren LogID zugeordnet sein wird.
|
15.02.2008, 16:03:47
|
Anfänger
|
|
Registriert seit: Feb 2008
Beiträge: 9
|
|
AW: Probleme mit Aggregatfunktion
Hallo Plasm,
probier mal ORDER BY ChangeDate, ich bin mir nicht sicher ob dieses einen Einfluss auf die "zufällig" von GROUP BY selectierte Zeile hat... zugegeben, ist ziemlich in die Luft geschossen...
|
15.02.2008, 16:22:39
|
Anfänger
|
|
Registriert seit: Feb 2008
Beiträge: 10
|
|
AW: Probleme mit Aggregatfunktion
Habe ich auch schon probiert ... klappt leider auch nicht.
ORDER BY wirkt erst im nachhinein auf die Ergebnis-Menge, ist also leider unbrauchbar.
Habe auch schon mit den Indexen rumgespielt, da ich hoffte, dass ich damit eine Vorsortierung hinbekomme, bisher aber auch noch ohne Erfolg
|
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
|
|
Forumregeln
|
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.
HTML-Code ist aus.
|
|
|
Alle Zeitangaben in WEZ +2. Es ist jetzt 11:04:54 Uhr.
|