Matthias Jütte: MAX-Wert einer Spalte mit restlichen Daten der Zeile auslesen

Hallo zusammen!

Ich würde gerne aus der Tabelle


| a | b | c |

| 2 | x | L |
| 3 | x | D |
| 5 | y | A |
| 2 | y | E |

den jeweils höchsten a-Wert einer jeden Gruppe von b-Datensätzen mit dem dazugehörigen c-Element auslesen. Rauskommen soll also

3,D
5,A.

Ich versuche das mit der Abfrage "SELECT MAX(a), c FROM tabelle GROUP BY b". Die liefert als Ergebnis aber

3,L
5,A.

Es wird also offensichtlich immer der erste in c gefundene Wert und der höchste a-Wert einer jeden Gruppe ausgelesen.

Kann mir jemand sagen, wie ich meine Abfrage ändern muß, um das gewünschte Ergebnis zu erlangen? Mir ist klar, daß ich erst den höchsten Wert der a-Spalte in eine MySQL-Variable auslesen kann, um dann nach dem dazugehörigen Wert der c-Spalte zu suchen (und das in eine Schleife packen kann), aber da das Problem in einem etwas komplizierteren als hier dargestellten Datengefüge auftritt, würde ich vorab gerne wissen, ob es auch eine Abfrage gibt, die mir direkt das gewünschte Ergebis liefert.

Gruß

Matthias

--
ss:| zu:| ls:[ fo:| de:] va:) ch:? sh:) n4:( rl:( br:> js:| ie:% fl:) mo:}
http://www.makaio.de/quotations
  1. Hallo Matthias

    Ich würde gerne aus der Tabelle


    | a | b | c |

    | 2 | x | L |
    | 3 | x | D |
    | 5 | y | A |
    | 2 | y | E |

    den jeweils höchsten a-Wert einer jeden Gruppe von b-Datensätzen mit dem dazugehörigen c-Element auslesen. Rauskommen soll also

    3,D
    5,A.

    Ich versuche das mit der Abfrage "SELECT MAX(a), c FROM tabelle GROUP BY b". Die liefert als Ergebnis aber

    Ein anständiges Datenbankmanagementsystems meckert bei einer solchen Abfrage. MySQL ist da meiner Ansicht nach zu großzügig.

    3,L
    5,A.

    Es wird also offensichtlich immer der erste in c gefundene Wert und der höchste a-Wert einer jeden Gruppe ausgelesen.

    Sagen wir so, es ist nicht vorhersagbar, welcher Wert bei c auftaucht. Du darfst Dich nicht darauf verlassen.

    Kann mir jemand sagen, wie ich meine Abfrage ändern muß, um das gewünschte Ergebnis zu erlangen?

    Ein vernünftiges DBMS vorausgesetzt, das Views kennt:

      
    CREATE VIEW vw_max_werte AS  
        SELECT  
            MAX(a) AS max_a,  
            b  
        FROM tabelle  
        GROUP BY b  
    /* natürlich nur einmal ausführen */  
      
    SELECT  
        a,  
        c  
    FROM tabelle AS t  
    INNER JOIN vw_max_werte AS m  
    ON t.a = m.max_a AND t.b = m.b  
    
    

    Mir ist klar, daß ich erst den höchsten Wert der a-Spalte in eine MySQL-Variable auslesen kann,

    Aha, Du verwendest MySQL. Das ist keine gute Nachricht.
    MySQL unterstützt Views erst in [http://dev.mysql.com/doc/mysql/en/views.html@title=Version 5.0]. Welche Version steht Dir zur Verfügung. Immer angeben!

    um dann nach dem dazugehörigen Wert der c-Spalte zu suchen (und das in eine Schleife packen kann), aber da das Problem in einem etwas komplizierteren als hier dargestellten Datengefüge auftritt, würde ich vorab gerne wissen, ob es auch eine Abfrage gibt, die mir direkt das gewünschte Ergebis liefert.

    Die oben vorgestellte Lösung funktioniert unter MS SQL-Server hervorragend :-)

    Freundliche Grüße

    Vinzenz

    1. yo,

      Ich versuche das mit der Abfrage "SELECT MAX(a), c FROM tabelle GROUP BY b". Die liefert als Ergebnis aber

      Ein anständiges Datenbankmanagementsystems meckert bei einer solchen Abfrage. MySQL ist da meiner Ansicht nach zu großzügig.

      mysql ist da genauso wenig großzügig wie andere dbms, außer dass es keine fehlermeldung ausgibt. aber nicht gruppierte und nicht aggregierte spalten mit in die select-ausgabe mit einzubeziehen geht auch bei mysql nur, wenn alle werte in der entsprechenden spalte der jeweiligen gruppierung gleich sind. mysql versucht damit eine weitere sortierung zu sparen. dass verwirrt aber mehr als es letztlich hilft.

      Aha, Du verwendest MySQL. Das ist keine gute Nachricht.
      MySQL unterstützt Views erst in [http://dev.mysql.com/doc/mysql/en/views.html@title=Version 5.0]. Welche Version steht Dir zur Verfügung. Immer angeben!

      views sind auch nicht unbedingt erforderlich, sondern man kann es mit korrelierenden unterabfragen lösen. die frage ist, ob seine version diese schon unterstützen, was ab 4.1 der fall sein sollte, bin mir da aber nicht ganz sicher.

      SELECT t1.a, t1.b, t.2c
      FROM tabelle AS t1
      WHERE t.1a = (SELECT MAX(a) FROM tabelle AS t2 WHERE t1.b=t2.b)

      Ilja

      1. Hallo!

        views sind auch nicht unbedingt erforderlich, sondern man kann es mit korrelierenden unterabfragen lösen. die frage ist, ob seine version diese schon unterstützen, was ab 4.1 der fall sein sollte, bin mir da aber nicht ganz sicher.

        Liegst mit deiner Vermutung richtig: http://dev.mysql.com/doc/mysql/en/subqueries.html

        Habe lokal auch 4.1.x, in der Produktivumgebung allerdings nur 4.0.15.

        Werde es dann wohl auf die umständliche Tour versuchen müssen, trotzdem danke für die Ideen (auch Vinzenz).

        Gruß

        Matthias

        --
        ss:| zu:| ls:[ fo:| de:] va:) ch:? sh:) n4:( rl:( br:> js:| ie:% fl:) mo:}
        http://www.makaio.de/quotations
        1. yo,

          Werde es dann wohl auf die umständliche Tour versuchen müssen, trotzdem danke für die Ideen (auch Vinzenz).

          eventuell könnte ein self-join noch helfen. bin mir aber da noch nicht so sicher, wie genau das aussehen sollte.

          Ilja