# Datenbankabfrage MySQL höchsten Wert aus Spalte



## Dimenson (27. November 2012)

Moin,

mal wieder stehe ich wie ein Ochse vorm Berg.

Ich habe eine Tabelle:

id
user_id
auktion_id
gebot

die enhält mehrere Datensätze:
id                      user_id            auktion_id              gebot
-------------------------------------------------------------------------
1                           1                         2                      100
2                           2                         2                      200
3                           1                         2                      300
4                           2                         2                      400
5                           1                         5                      100
6                           2                         5                      200
7                           1                         5                      300

Jetzt möchte gerne als user_id 1 eine Liste dargestellt bekommen wo ich momentan der Höchstbieter bin. Jetzt bin ich gerade momentan am rotieren wie ich meine SQL Abfrage gestalte. 
Habt ihr mir da vllt einen Tipp ?

Ich könnte natürlich jeden einzelnen Datensatz mit WHERE user_id 1 ist abfragen und gegen kontrollieren mit einer weiteren SQL Anfrage ob ich wirklich der Höchstbietende der Auktion bin. Aber gibt es eine Möglichkeit mit nur einer SQL Anfrage das rauszufinden ? Bestimmt, aber da ich mich noch wirklich mit komplexere Anfragen in MySQL auskenne, habt ihr mir vllt einen Rat.

Danke


----------



## mike-pretzlaw (27. November 2012)

In diesem Fall kannst deinen SELECT nehmen und diesem ein Order By und ein Group By geben. Am Ende dürfte ein Sub-Select herauskommen ähnlich diesem:

http://www.tutorials.de/relationale-datenbanksysteme/305152-group-kombination-mit-order-mysql.html


----------



## Yaslaw (27. November 2012)

Auf die Schnelle und ungetestet

```
SELECT
	max_per_au.auktion_id,
	max_per_au.au_max AS gebot
FROM
	(
		SELECT
			auktion_id,
			MAX(gebot) AS au_max
		FROM
			gebot
		GROUP BY
			auktion_id
	) AS max_per_au
	INNER JOIN (
		SELECT
			auktion_id,
			MAX(gebot) AS my_max
		FROM
			gebote
		WHERE
			-- Hier deine User-ID einfügen
			user_id = 123
		GROUP BY
			auktion_id
	) AS max_for_me
		ON max_per_au.auktion_id = max_for_me.auktion_id
		AND max_per_au.au_max = max_for_me.my_max
```


----------



## holzmensch (27. November 2012)

Ich weiß nicht ob die Version vom Vorgänger funktioniert, habe aber hier eine kürzere getestete Variante:


```
SELECT 
	u.user_id,
	u.auktion_id,
	u.gebot
FROM 
	gebote u,
	gebote alle
WHERE
	u.user_id = 1 AND
    alle.auktion_id = u.auktion_id
GROUP BY	
	u.auktion_id
HAVING
	u.gebot >= MAX(alle.gebot)
```

grüße


----------



## Dimenson (27. November 2012)

Also das scheint gut zu funktionieren. Danke Yaslaw und Respekt weil ungetestet und es funktioniert ^^. 

Hier könnt ihr mal ein bißchen schmunzeln mit was ich gerade eben noch ein bißchen getestet hatte:

```
SELECT * FROM 
   auktionshaus_gebote 
WHERE 
   user_id='".$userinfo."' AND 
   user_id=(SELECT 
                         user_id 
                   FROM 
                         auktionshaus_gebote 
                   ORDER BY ABS(preis) DESC LIMIT 1)
```

Danke


----------



## Yaslaw (27. November 2012)

@holzmensch.
Mach Sinn. Aber im HAVING sollte von u.gebot auch das MAX() genommen werdena usser du willst danach gruppieren. (Es kann ja sein, dass ein User mehrere Gebote abgegeben hat.


----------



## Dimenson (27. November 2012)

@Yaslaw und holzmensch : Welche Variante ist denn sinnvoller? Und ob ich nun ein paar Zeilen spare oder nicht, spielt keine Rolle. Mir kommt es eher auf die Performance an.

Ich glaube ich habe beide Varianten begriffen,
@holzmensch kann es dennoch sein das bei deiner Variante hier:

```
FROM 
    gebote USER,
    gebote alle
```

nach gebote ein "AS" fehlt oder muss das gar nicht angegeben werden ?

Danke

Es soll nur das Maximal Gebot abgefragt werden.


Yaslaw hat gesagt.:


> @holzmensch.
> Mach Sinn. Aber im HAVING sollte von u.gebot auch das MAX() genommen werdena usser du willst danach gruppieren. (Es kann ja sein, dass ein User mehrere Gebote abgegeben hat.


----------



## holzmensch (27. November 2012)

Yaslaw hat gesagt.:


> @holzmensch.
> Mach Sinn. Aber im HAVING sollte von u.gebot auch das MAX() genommen werdena usser du willst danach gruppieren. (Es kann ja sein, dass ein User mehrere Gebote abgegeben hat.



Klar, wenn man mehrere Angebote eingeben kann und alle gespeichert werden, dann sollte man MAX() in HAVING hinzufügen und auch im SELECT. Wollte aber dem Author nciht die ganze Arbeit abnehmen! 

PS: Hier dann die Version mit dem MAX für multiple Gebote

```
SELECT 
    u.user_id,
    u.auktion_id,
    MAX(u.gebot) as user_max_gebot
FROM 
    gebote u,
    gebote alle
WHERE
    u.user_id = 1 AND
    alle.auktion_id = u.auktion_id
GROUP BY    
    u.auktion_id
HAVING
    MAX(u.gebot) = MAX(alle.gebot)
```

Keine Ahnung was performanter ist, musst mal testen, falls du echt viele Abfragen hast. Aus der Anzahl der Zeilen kann man leider nicht auf die Performance schließen, aber viel werden sich die Varianten da nicht nehmen.


----------



## Dimenson (27. November 2012)

Das befürchte allerdings auch fast 

Hm, jetzt habe ich doch nochmal ne kurze Frage.

Wie zähle ich nun die gesamten Gebote einer Auktion.
Das habe ich nun bei mir jetzt mal getestet:

```
SELECT 
	u.user_id, 
	u.auktionshaus_id, 
	auktionshaus.domain, 
	auktionshaus.datum_ende, 
	MAX(u.preis) AS user_max_gebot 
FROM 
	auktionshaus_gebote u, 
	auktionshaus_gebote alle 
JOIN 
	auktionshaus 
ON 
	auktionshaus.id=alle.auktionshaus_id 
WHERE 
	u.user_id = '44' 
AND 
	alle.auktionshaus_id = u.auktionshaus_id 
AND 
	auktionshaus.datum_ende > '1354038856' 
GROUP BY 
	u.auktionshaus_id 
HAVING MAX(u.preis) = MAX(alle.preis)
```

Leider hat mein Test:

```
SELECT 
	u.user_id, 
	u.auktionshaus_id, 
	auktionshaus.domain, 
	auktionshaus.datum_ende, 
	MAX(u.preis) AS user_max_gebot,
        u.count(*) AS gebote
FROM 
	auktionshaus_gebote u, 
	auktionshaus_gebote alle 
JOIN 
	auktionshaus 
ON 
	auktionshaus.id=alle.auktionshaus_id 
WHERE 
	u.user_id = '44' 
AND 
	alle.auktionshaus_id = u.auktionshaus_id 
AND 
	auktionshaus.datum_ende > '1354038856' 
GROUP BY 
	u.auktionshaus_id 
HAVING MAX(u.preis) = MAX(alle.preis)
```

nicht funktioniert.


----------



## holzmensch (27. November 2012)

joine das ganze wie ich es schon gemacht habe - übersichtshalber!
Funktioniert der Spaß ohne dein aktionshaus join? Was gibt es für eine Fehlermeldung?


----------



## Dimenson (27. November 2012)

Stehe momentan auf dem Schlauch und weiß leider wie du es meinst. Sorry

Wenn ich das nun ausführe:

```
SELECT 
	u.user_id, 
	u.auktionshaus_id, 
	b.domain,
	MAX(u.preis) AS user_max_gebot,
	COUNT(u.preis) AS gebote
FROM 
	auktionshaus_gebote u, 
	auktionshaus_gebote alle,
	auktionshaus b
WHERE 
	u.user_id = '44' 
GROUP BY 
	u.auktionshaus_id 
HAVING MAX(u.preis) = MAX(alle.preis)
```

Bekomme ich bei Gebote 36.
Es sind aber nur 3.

Ah ich habe es wohl hinbekommen:

```
SELECT 
	u.user_id, 
	u.auktionshaus_id, 
	b.domain,
	MAX(u.preis) AS user_max_gebot,
    (SELECT count(*) FROM auktionshaus_gebote WHERE auktionshaus_id=u.auktionshaus_id) AS gebote
FROM 
	auktionshaus_gebote u, 
	auktionshaus_gebote alle,
	auktionshaus b

WHERE 
	u.user_id = '44' 
GROUP BY 
	u.auktionshaus_id 
HAVING MAX(u.preis) = MAX(alle.preis)
```

@holzmensch habe gerade bei deiner Variante festgestellt, das ich immer nur eine Auktion auslesen kann und zwar die mit dem höchste Gebot. Und ich denke mal das dass mit MAX(alle.preis) so ist.


----------



## holzmensch (27. November 2012)

Ja, wolltest doch die Gebote eines Users haben, wo der User der Höchstbietender ist. COUNT würde auch ohne den innerselect klappen, wenn du alle.gebote zählst und nicht user.gebote!


----------



## Dimenson (27. November 2012)

Ja, ich wollte gerne die Gebote aller Auktionen, wo der User der Höchstbietende ist, anzeigen lassen. Bei deiner Variante funktioniert das halt nicht. Es werden alle Auktionen zusammen gemischt und nur das Höchste Gebot rausgepickt.

Hallo,

so scheint es am besten zu funktionieren:

```
$sql="SELECT
        max_per_au.auktionshaus_id,
        max_per_au.au_max AS gebot,
        max_per_au.gebote AS gebote,
        die_auktion.domain AS domain,
        die_auktion.datum_ende AS datum_ende
    FROM
        (
            SELECT
                auktionshaus_id,
                MAX(preis) AS au_max,
                COUNT(*) AS gebote
            FROM
                auktionshaus_gebote
            GROUP BY
                auktionshaus_id
        ) AS max_per_au
        INNER JOIN (
            SELECT
                auktionshaus_id,
                MAX(preis) AS my_max
            FROM
                auktionshaus_gebote
            WHERE
                user_id = '".$userinfo['id']."'
            GROUP BY
                auktionshaus_id
        ) AS max_for_me
            ON max_per_au.auktionshaus_id = max_for_me.auktionshaus_id
            AND max_per_au.au_max = max_for_me.my_max
        INNER JOIN (
            SELECT 
                id,
                domain,
                datum_ende
            FROM 
                auktionshaus
        ) AS die_auktion 
        ON max_per_au.auktionshaus_id = die_auktion.id";
```


----------



## holzmensch (28. November 2012)

klar funktioniert das, COUNT(alle.preis) as anzahl, aber mach wie du willst.
Das 30 zeilige SQLStatement ist um einiges einladender und wartbarer! ;-)


----------

