kleines GROUP BY - Problem

loddarmattheus

Erfahrenes Mitglied
Hallo Leute,
habe mal wieder ein kleines Problem aber für euch Experten ist das hoffentlich kein Problem. Meine MySQL sieht in etwa so aus:

1656093498462.png

Ziel ist es, als Ausgabe an einem speziellen Tag die "jüngste" time für jeden Kunden auszugeben. Mein Code sieht so aus:


PHP:
function Test5($db,$table,$datum)
    { 
    $statement = $db->prepare("SELECT * FROM $table WHERE date LIKE $datum GROUP BY kunde");
    if($statement->execute())
        {
        while($row = $statement->fetch())
            {
            echo $row['date']." ".$row['kunde']." ".$row['time']."<br />"; //alle namen
            }           
        }
    }

Aber das Ergebnis stimmt an einer Stelle nicht:

1656093745059.png
Bei Katarina Osterburg sollte 1430 statt 1500 stehen, da dies der jüngste Eintrag ist. Bei den anderen stimmt es dummerweise und ich habe keine Erklärung dafür.
Könnte bitte einer der Experten mir die Richtung weisen?

Danke Loddar
 
Ich bin nicht wirklich der Datenbankexperte aber dieses Problem lässt sich, denke ich, relativ leicht lösen:
Du hast in deiner Abfrage nirgends angegeben, dass Du den Minimalwert von time haben willst. Versuche es so:
Code:
SELECT MIN(time), kunde, date FROM `kunden` GROUP BY kunde
Getestet mit 20 Datensätzen und 4 Kunden und hat augenscheinlich funktioniert.
 
Code:
SELECT MIN(time), kunde, date FROM `kunden` GROUP BY kunde
Unschön. Für date wurde nicht bestimmt, was gemacht werden soll. Einige Datenbanken lassen das zu und machen selber einen GROUP BY auf die Felder die weder im GROUP BY noch mit einer Aggregatsfunktion (min, max, count etc.) versehen sind. Andere DBA werfen zu recht ein Fehler, denn es ist ein Fehler.
Code:
SELECT MIN(time), kunde, date FROM `kunden` GROUP BY kunde, date
 
Und wenn du
a) date und time NICHT trennen würdest,
oder
b) es schon trennst, dann den richtigen Datentyp verwenden würdest,
wäre es sogar noch einfacher.

Ausserdem: Benutze nie reservierte Wörter als Feldnamen.
Ist ne tickende Zeitbombe
 
Andere Variante ohne Min/Max zu verwenden (was manchmal von Nöten ist)
Getestet in SQLite
MySQL sollte ROW_NUMBER können (Syntax mag leicht anderst sein)
SQL:
SELECT 
k1.id,
k2.kunden_id,
k2.datum,
k2.zeit,
k2.dauer,
k2.kunde 
FROM tbl_kunde as k1 
INNER JOIN 
    (SELECT 
        id, 
        kunden_id, 
        datum, 
        zeit, 
        dauer, 
        kunde, 
        ROW_NUMBER() OVER(PARTITION BY kunden_id, datum ORDER BY kunden_id, datum, zeit) as RN 
        FROM tbl_kunde) as k2 
ON k1.id=k2.id 
WHERE k2.rn=1
ORDER BY k2.kunde
 

Neue Beiträge

Zurück