Dieter: MySQL: LEFT JOIN mit ORDER BY id DESC LIMIT 1

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

  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?

    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.

    1. 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

      1. 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.

        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.

        1. 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 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.

          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

          1. [.... lange ausführliche Erklärung .....]

            Danke, ich werd mir das ein paarmal durchlesen und dann verstehen (hoffentlich).

            Struppi.

  2. 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