Datenbankfunktion min() macht nicht, was ich möchte

Olaf Lehmann

Mitglied
Hallo allerseits!

Also...folgendes Problem hab ich...

Ich mache eine Datenbankabfrage, die so aussieht:
PHP:
	  $sql = "select min(secondes) as seco, datecourse, nomuser from tbl_course,tbl_utilisateur,tbl_tour where tbl_course.idcircuit='".$id."' and tbl_tour.IdCourse = tbl_course.idcourse and tbl_tour.IdPilote = tbl_utilisateur.iduser  group by nomuser order by seco asc";
Alles wunderbar. Wenn ich auf
PHP:
$row[ seco ]
zugreife, wird der kleinste Wert ausgegeben, so wies sein soll. Nun möchte ich aber, das die anderen Daten
PHP:
$row[ datecourse ]
,usw. aus dem gleichen Datensatz stammen. Das tun sie nämlich nicht. :confused:
Mir wird genau die richtige Anzahl an Datensätzen angeboten, also scheinen die drei Tabellen richtig verknüpft zu sein.

Gibt es eine andere, passendere Möglichkeit als min() ?

Danke im Voraus!
 
Kann das funktionieren?

Man(n) muss doch jede "Nicht-Kombinations-Spalte" (oder wie das heißt) im Group By angeben?

Versuch mal, dass du im GROUP BY die Spalte datecourse hinzugibst....

greez
THEJS
 
MySQL bescheisst und nimmr bei eine GROUP BY automatisch alle Felder die keine GroupBy-Funktion (also min(), max() etc) haben in den GROUP BY.

Das sorgt dazu, dass auch nach datecourse auch gruppiert wird.

Mit Subqueries würde sich das lösen lassen. Jedoch seh ich nicht aus welchen Tabellen die 3 Felder stammen, so dass ich hier kein Vorschlag-SQL erstellen kann.
 
Danke erstmal!

@THEJES: Dein Tipp hilft nicht wirklich weiter. Je mehr ich hinter Group By schreibe, umso mehr Datensätze findet er. Und mein Problem ist grade, dass zwar alles läuft, dass aber wegen der vielen Daten unser Webserver abbricht.

@yaslaw: Der Fall liegt eigentlich sehr einfach. die Daten um die es geht sind letztendlich alle in der gleichen Tabelle.
Ich versuche das eigentliche Problem nochmal einzugrenzen, so dass es am schnellsten zu durchschauen ist.( An den konkreten Fall kann ichs dann selber anpassen denk ich.)
Code:
$sql = "select min(secondes) as seco,nomuser,datecourse, Temps from tbl_tour where group by nomuser order by seco asc";
Es handelt sich übrigens um eine Bestzeitenanzeige für eine Rennliga. In secondes stecken die Rundenzeiten. nomuser ist der Fahrername. Es sollen von jedem Fahrer die beste Rundenzeit aufgelistet werden. datecourse und Temps sind Zusatzinfos, die sich auf die entsprechen Runde beziehen müssen.
Was konkret in dem Falle geschieht ist wie gesagt: Die Rundenzeiten aus secondes werden korrekt geordnet und auch für jeden Fahrer nur die beste zurückgeliefert. Aber datecourse,Temps liefert einfach den ersten Wert zurück, der gefunden wird.
Ich hoffe das Problem ist jetzt leicht verständlich dargestellt.

MfG Olaf
 
@yaslaw
Ich würde das nicht bescheissen nennen, denn laut SQL MÜSSEN alle Spalten ohne arithmetische Operatoren (heissts ^^) im GROUP BY angegeben werden

@Threadersteller
Falsche Bedingungen udg können dazu führen dass die Zeilen der Tabellen in allen möglichkeiten angezeigt werden (AnzahlZeilenTabelle1 * AnzahlZeilenTabelle2 * AnzahlZeilenTabelle3)
Da kann ich mir schon vorstellen, dass zu viele Daten heraus kommen!

PHP:
$sql = "select nomuser, datecourse, Temps, MIN(seconds) from tbl_tour group by 1, 2, 3 order by 4 asc";

Und das funktioniert wirklich nicht?
Schau dir das nochmal an!
Ich bin mir zu einer relativ hohen Prozentzahl sicher, dass das funktionieren wird.

greez
THEJS
 
Ich versteh wo dein Problem leigt. Jedoch weiss ich immer noch nicht zu welchen Tabellen welche Felder gehören. ich habe jetzt mal geraten. Es ist sicher falsch.

Aber etwa so könnte die Lösung aussehen
SQL:
SELECT
	c.seco, 
	u.datecourse, 
	u.nomuser 
FROM
	(SELECT
		MIN(secondes) as seco,
		iduser
	FROM tbl_course
	WHERE idcircuit='".$id."' 
	GROUP BY iduser) AS c,
	tbl_utilisateur AS u,
	tbl_tour AS t
WHERE
	and t.IdCourse = c.idcourse 
	and t.IdPilote = u.iduser  
ORDER BY c.seco ASC


@Yaslaw
Ich würde das nicht bescheissen nennen, denn laut SQL MÜSSEN alle Spalten ohne arithmetische Operatoren (heissts ) im GROUP BY angegeben werden
Bescheissen in dem Sinn, dasse s zu unsauberem Programmieren verleitet und kein Standart-SQL ist. DIeser Thread ist genau wegen dieser unschönen Sache hier. Währe es nach Standarts, würde das SQL ein Fehler werfen un ncith einfach etwas was MySQL meint sei dass was der User haben wolle.
 
Zuletzt bearbeitet von einem Moderator:
Doofe Zwischenfrage:
geht die Where-Clause überhaupt, müsste es nicht so aussehen?

SQL:
SELECT
    c.seco,
    u.datecourse,
    u.nomuser
FROM
    (SELECT
        MIN(secondes) AS seco,
        iduser
    FROM tbl_course
    WHERE idcircuit='".$id."'
    GROUP BY iduser) AS c,
    tbl_utilisateur AS u,
    tbl_tour AS t
WHERE
    t.IdCourse = c.idcourse
    AND t.IdPilote = u.iduser  
ORDER BY c.seco ASC
 
Zuletzt bearbeitet von einem Moderator:
Hast du dir die Ergebnistabelle in phpmyadmin mal angeschaut?
Das tu ich immer, wenn ich eine etwas größere SQL Abfrage baue. So sehe ich gleich nach der Ausführung was bei rauskommt.
 
Danke für die Antworten!
Bin jetzt erst zum Probieren gekommen.

Zum Vorschlag von THEJES: Es funktioniert schon, wenn ich alle anderen Spalten außer secondes bei GROUP BY angebe, nützt mir aber nix, weil dann bei manchen Strecken 50000 Datensätze gefunden werden und die nötige Auswertung der Daten (das Heraussuchen der wenigen wirklich besten Runden) so lange dauert, dass dann unser Server irgendwann Schluss macht. Es funktioniert dann nicht besser als ganz ohne MIN() GROUP BY Befehle.

@YASLAW & 00d4vid:
Euren Vorschlag kriege ich nicht zum Laufen, weil:
Leider müssen in der inneren SELECT Abfrage in der Klammer zwei Tabelle geöffnet werden und dann funktioniert das "AS c" hinter ")" scheinbar nicht (im Beispiel bei mir AS t wegen der wie vermutet vertauschten Tabellennamen).

Also ich schreib mal hin, was in welcher Tabelle steckt:
tbl_course: idcourse,idcircuit,datecourse
tbl_utilisateur: nomuser, iduser
tbl_tour: IdCourse,IdPilote,TypeTour,Temps,Infos,voiture,secondes

Es gilt:
idcourse=IdCourse (Kennzahl für jedes Rennen)
iduser=IdPilote (Kennzahl für jeden Fahrer)

Auf die richtigen Tabellen übertragen, sieht Euer Code so aus:
Code:
$sql = "SELECT t.seco, c.datecourse, u.nomuser,t.voiture,t.Infos,t.Temps,t.TypeTour FROM
( SELECT MIN(secondes) AS seco FROM tbl_tour,tbl_course
WHERE idcircuit='".$id."' AND tbl_tour.IdCourse = tbl_course.idcourse 
GROUP BY IdPilote ) AS t,
tbl_utilisateur AS u,
tbl_course AS c
WHERE c.idcircuit='".$id."' AND t.IdCourse = c.idcourse AND t.IdPilote = u.iduser
ORDER BY seco ASC";
Das Problem ist wie gesagt, dass ich in der inneren Abfrage zwei Tabellen öffnen muss, weil in tbl_tour nicht vermerkt ist um welche Strecke es sich handelt...und die Zeiten dürfen immer nur von der über $id gewählten Strecke genommen werden.

Gibts ne Lösung für das Problem?

MfG Olaf
 
Zuletzt bearbeitet:
Zurück