# Ausgabe der Rows mit höchstem Wert X einer Gruppe y,z ?



## mfernau (6. Mai 2011)

Hallo Leute,

ich stehe gerade auf dem Schlauch und habe mir hier mittlerweile ein Query aufgebaut bei dem ich nicht mehr durchblicke 

Simples Beispiel.

Gegeben sein folgende Tabellen `service` `service_version`
Tabelle service:

```
+----++-----+
| id | name |
+----++-----+
```

Tabelle service_version

```
+----++------+------+-----------+-----------+-------------+
| id | build | beta | api_major | api_minor | downloadURL |
+----++------+------+-----------+-----------+-------------+
```

Außer 'name' und downloadURL (varchar) sind alle Columns int

Es geht hierbei um eine Datenbank die Versionsinformationen von Plugins zu einem Server hält.
Was ich nun gerade suche ist ein Select-Statement, dass mir nur eine Row pro Gruppierung aus api_major, api_minor und build für ein bestimmten Service ausgibt. Und zwar die Zeile mit dem höchsten build.

Naiv könnte man jetzt folgendes tun:

```
SELECT * 
  FROM 
    `service` 
  NATURAL LEFT JOIN 
    `service_version`
  GROUP BY api_major, api_minor, beta
```

Als Ergebnis kommt dabei so etwas heraus:

```
+---------------+-------+------+-----------+-----------+
| id | name     | build | beta | api_major | api_minor |
+---------------+-------+------+-----------+-----------+
| 1  | Service1 | 4     | 0    | 1         | 0         |
| 1  | Service1 | 1     | 1    | 1         | 0         |
| 1  | Service1 | 6     | 1    | 1         | 1         |
| 1  | Service1 | 8     | 1    | 2         | 0         |
+---------------+-------+------+-----------+-----------+
```

Aber das Ergebnis von group by ist nicht sortiert. Group by liefert mir irgend eine Zeile für eine Gruppe - nicht notwendigerweise die mit dem höchsten build. Eher sogar das Gegenteil. Z.b. gibt es die build-Version 9 für die Gruppe mit beta == 1, api_major == 2 und api_minor == 0

Wie baut man so ein Select bei dem man nur eine bestimmte Zeile einer Gruppe bekommt? Evtl sehe ich auch den Wald vor lauter Bäumen nicht mehr...

Besten Dank und viele Grüße,
Martin


----------



## Gast2 (7. Mai 2011)

Bau doch einfach noch einen Select drum rum?

*untested*

```
SELECT * FROM (
SELECT * 
  FROM 
    `service` 
  NATURAL LEFT JOIN 
    `service_version`
  GROUP BY api_major, api_minor, beta
) ORDER BY build LIMIT 1
```

Oder so...


----------



## mfernau (7. Mai 2011)

Das hätte keinen Effekt - Das Problem ist doch dass Group By eigentlich für Gruppenoperatoren wie sum, max und so weiter benutzt wird. Wenn aber kein solcher Operator für eine Spalte einer Group By Klausel verwendet wird ist das Ergebnis undefiniert.
Group by liefert dann also irgend eine Zeile dieser Gruppe.
was maximal ginge wäre sowas hier

```
SELECT * 
  FROM 
    `service` 
  NATURAL LEFT JOIN 
    (select * from service_version order by build desc) service_version
  GROUP BY api_major, api_minor, beta
```

Aber so richtig gefallen will mir das mit den Subselects und der vergewaltigten group by klausel nicht. Denn das hier ist nur ein Beispiel - diese Abfrage die ich hier suche ist integriert in einer anderen abfrage die sich zusammensetzt aus allen installierten services. Der Aufwand solcher Abfragen steigt also Quadratisch


----------

