MySQL: LEFT JOIN mit ORDER BY id DESC LIMIT 1
Dieter
- datenbank
Hallo,
also ich habe zwei Tabellen:
kategorie:
id name
beitrag:
id kategorieid text lastmodification
So jetzt möchte ich die ganze Tabelle 'kategorie' ausgeben, und dazu immer den Beitrag, mit dem höchsten 'lastmodification'.
In PHP meine ich dies so:
<?php
while($row = mysql_fetch_object("SELECT * FROM kategorie"))
{
$beitrag_erg = mysql_query("SELECT * FROM beitrag WHERE kategorieid = '$row->id' ORDER BY lastmodification DESC LIMIT 1";
}
?>
Kann ich diese beiden Querys jetzt per LEFT JOIN o.ä. zusammenführen (alelrdings MySQL3.x kompatibel)
ca. so:
SELECT k.*, b.* FROM kategorie k
LEFT JOIN beitrag b ON (b.kategorieid = k.id ORDER BY lastmodification DESC LIMIT 1)
Kann mir jmd. weiterhelfen?
MFG
Dieter
Kann ich diese beiden Querys jetzt per LEFT JOIN o.ä. zusammenführen (alelrdings MySQL3.x kompatibel)
ca. so:
SELECT k.*, b.* FROM kategorie k
LEFT JOIN beitrag b ON (b.kategorieid = k.id ORDER BY lastmodification DESC LIMIT 1)Kann mir jmd. weiterhelfen?
Wenn ich dich richtig versteh müßte es so gehen:
SELECT k.*, b.*
FROM kategorie k LEFT JOIN beitrag b ON b.kategorieid = k.id
GROUP BY b.kategorieid
ORDER BY b.kategorieid, lastmodification DESC
Struppi.
yo,
Wenn ich dich richtig versteh müßte es so gehen:
SELECT k.*, b.*
FROM kategorie k LEFT JOIN beitrag b ON b.kategorieid = k.id
GROUP BY b.kategorieid
ORDER BY b.kategorieid, lastmodification DESC
die query ist vom inhaltlichen mal abgesehen schon syntaktisch falsch. es ist das alte leid bei mysql mit GROUP BY. lies noch mal die doku und du wirst sehen, dass dies auch ohne fehlermeldung fehlerhaft ist.
Ilja
SELECT k.*, b.*
FROM kategorie k LEFT JOIN beitrag b ON b.kategorieid = k.id
GROUP BY b.kategorieid
ORDER BY b.kategorieid, lastmodification DESCdie query ist vom inhaltlichen mal abgesehen schon syntaktisch falsch. es ist das alte leid bei mysql mit GROUP BY. lies noch mal die doku und du wirst sehen, dass dies auch ohne fehlermeldung fehlerhaft ist.
Also bei mir läuft die Abfrage ohne Fehlermeldung durch.
Aber ich hab schon öfters hier gelesen das dies oder jenes bei einem group by nicht stimmt, verstanden habe ich das nie. An welcher Stelle in der Doku steht das?
Struppi.
Hallo
SELECT k.*, b.*
FROM kategorie k LEFT JOIN beitrag b ON b.kategorieid = k.id
GROUP BY b.kategorieid
ORDER BY b.kategorieid, lastmodification DESCdie query ist vom inhaltlichen mal abgesehen schon syntaktisch falsch. es ist das alte leid bei mysql mit GROUP BY. lies noch mal die doku und du wirst sehen, dass dies auch ohne fehlermeldung fehlerhaft ist.
Also bei mir läuft die Abfrage ohne Fehlermeldung durch.
Ja klar schluckt MySQL so etwas ohne Fehlermeldung. Das kritisiert hier nicht nur Ilja, das prangern auch andere an, z.B. ich.
Aber ich hab schon öfters hier gelesen das dies oder jenes bei einem group by nicht stimmt, verstanden habe ich das nie.
Eine ähnliche Erklärung wie die folgende wollte ich Dir bereits bei Deiner letzten Anfrage posten, da war aber der Thread schon im Archiv:
kategorie:
id name
beitrag:
id kid text lastmodification
SELECT k.*, b.*
FROM kategorie k LEFT JOIN beitrag b ON b.kategorieid = k.id
GROUP BY b.kid
ORDER BY b.kid, lastmodification DESC
entspricht
SELECT
k.id,
k.name,
b.id,
b.kid,
b.text,
b.lastmodification
FROM kategorie k
LEFT JOIN beitrag b ON b.kid = k.id
GROUP BY b.kid
ORDER BY b.kid, lastmodification DESC
Nehmen wir
k
id name
1 alpha
2 beta
3 gamma
b
id name b.kid b.text b.lastmodification
1 A 1 ABC 2005-09-08
2 B 1 DEF 2005-09-09
3 C 2 GHI 2005-09-07
4 D 2 JKL 2005-09-08
5 E 1 MNO 2005-09-10
6 F 2 PQR 2005-09-06
Somit haben wir bei
SELECT
k.id,
k.name,
b.id,
b.kid,
b.text,
b.lastmodification
FROM kategorie k
LEFT JOIN beitrag b ON b.kid = k.id
die Ergebnismenge
k.id k.name b.id b.kid b.text b.lastmodification
1 alpha 1 1 ABC 2005-09-08
1 alpha 2 1 DEF 2005-09-09
1 alpha 5 1 MNO 2005-09-10
2 beta 3 2 GHI 2005-09-07
2 beta 4 2 JKL 2005-09-08
2 beta 6 2 PQR 2005-09-06
3 gamma NULL NULL NULL NULL
dabei ist die "Ordnung" dieser Datensätze zufällig.
Nächster Schritt:
Nun verwendest Du GROUP BY b.kid. Für alle weiteren Felder gilt,
dass sie nicht in GROUP BY aufgeführt werden, dass auch keine
Aggregatsfunktion verwendet wird. MySQL läßt dies zu und weist
darauf hin, dass der Wert in diesen Spalten _zufällig_ ist.
SELECT
k.id,
k.name,
b.id,
b.kategorieid,
b.text,
b.lastmodification
FROM kategorie k
LEFT JOIN beitrag b ON b.kid = k.id
GROUP BY b.kid
Andere SQL-Dialekte weisen dieses Statement als fehlerhaft
zurück.
Nun ja, eine mögliche Ergebnismenge dieser Abfrage in MySQL
_könnte_ dies sein:
k.id k.name b.id b.kid b.text b.lastmodification
2 beta 3 2 GHI 2005-09-07
1 alpha 1 1 ABC 2005-09-08
3 gamma NULL NULL NULL NULL
Im dritten Schritt wird die Ergebnismenge sortiert:
SELECT
k.id,
k.name,
b.id,
b.kid,
b.text,
b.lastmodification
FROM kategorie k
LEFT JOIN beitrag b ON b.kid = k.id
GROUP BY b.kid
ORDER BY b.kid, lastmodification DESC
k.id k.name b.id b.kid b.text b.lastmodification
1 alpha 1 1 ABC 2005-09-08
2 beta 3 2 GHI 2005-09-07
3 gamma NULL NULL NULL NULL
Nun hast Du weder für k.id noch für b.id den
Datensatz mit der letzten "lastmodification"
erwischt. Selbst wenn Du jetzt sagst: Es wird zuerst sortiert
und dann ausgewählt, garantiert Dir MySQL _nicht_, dass es den
_ersten_ Wert nimmt. MySQL sagt: Der Wert ist zufällig. Mein oben
beschriebenes Ergebnis ist für MySQL zulässig und akzeptabel. Es
ist aber nicht das gewünschte Ergebnis. Dies liegt daran, dass
das Statement schlicht und einfach für das Gewünschte falsch ist.
An welcher Stelle in der Doku steht das?
Zum Beispiel unter:
http://dev.mysql.com/doc/mysql/en/group-by-hidden-fields.html, ich zitiere:
<zitat>
Do not use this feature if the columns you omit from the GROUP BY part are not unique in the group! You get unpredictable results.
</zitat>
Also: Unvorhersehbare Resultate ist doch eindeutig genug. Willst Du Dich auf "unvorhersehbare Resultate" verlassen? Wirklich? Das ist bei Deinem Statement der Fall!
Das ganze auf Deutsch: http://dev.mysql.com/doc/mysql/de/group-by-functions.html
Freundliche Grüße
Vinzenz
[.... lange ausführliche Erklärung .....]
Danke, ich werd mir das ein paarmal durchlesen und dann verstehen (hoffentlich).
Struppi.
yo,
Kann ich diese beiden Querys jetzt per LEFT JOIN o.ä. zusammenführen (alelrdings MySQL3.x kompatibel)
ohne unterabfragen sehe ich keine möglichkeit, dass mit einer abfrage abzuarbeiten. aber vielleicht hat jemand anderes eine bessere idee.
Ilja