Dies ist eine klassische Hürde, auf die die meisten MySQL-Programmierer stoßen.
- Sie haben eine Spalte
ticket_id
das ist das Argument fürGROUP BY
. Eindeutige Werte in dieser Spalte definieren die Gruppen. - Sie haben eine Spalte
incoming_time
das ist das Argument fürMAX()
. Der größte Wert in dieser Spalte über die Zeilen in jeder Gruppe wird als Wert vonMAX()
zurückgegeben . - Sie haben alle anderen Spalten der Tabelle Artikel. Die für diese Spalten zurückgegebenen Werte sind willkürlich und stammen nicht aus derselben Zeile wie
MAX()
Wert auftritt.
Die Datenbank kann nicht ableiten, dass Sie Werte aus derselben Zeile wünschen, in der der Maximalwert auftritt.
Denken Sie an die folgenden Fälle:
-
Es gibt mehrere Zeilen, in denen derselbe Maximalwert auftritt. Welche Zeile soll verwendet werden, um die Spalten von
article.*
anzuzeigen ? -
Sie schreiben eine Abfrage, die sowohl
MIN()
zurückgibt und dasMAX()
. Dies ist zulässig, aber welche Zeile solltearticle.*
sein anzeigen?SELECT article.* , MIN(article.incoming_time), MAX(article.incoming_time) FROM ticket, article WHERE ticket.id = article.ticket_id AND ticket.queue_id = 1 GROUP BY article.ticket_id
-
Sie verwenden eine Aggregatfunktion wie
AVG()
oderSUM()
, wobei keine Zeile diesen Wert hat. Wie soll die Datenbank erraten, welche Zeile angezeigt werden soll?SELECT article.* , AVG(article.incoming_time) FROM ticket, article WHERE ticket.id = article.ticket_id AND ticket.queue_id = 1 GROUP BY article.ticket_id
In den meisten Datenbankmarken – ebenso wie im SQL-Standard selbst – sind Sie nicht erlaubt eine Abfrage wie diese zu schreiben, wegen der Mehrdeutigkeit. Sie können keine Spalte in die Auswahlliste aufnehmen, die sich nicht in einer Aggregatfunktion befindet oder in GROUP BY
benannt ist Klausel.
MySQL ist freizügiger. Es lässt Sie dies tun und überlässt es Ihnen, Abfragen ohne Mehrdeutigkeit zu schreiben. Wenn Sie Mehrdeutigkeit haben, werden Werte aus der Zeile ausgewählt, die physisch an erster Stelle in der Gruppe steht (dies liegt jedoch an der Speicher-Engine).
Für das, was es wert ist, hat SQLite auch dieses Verhalten, aber es wählt das letzte Zeile in der Gruppe, um die Mehrdeutigkeit aufzulösen. Stelle dir das vor. Wenn der SQL-Standard nicht vorschreibt, was zu tun ist, liegt es an der Herstellerimplementierung.
Hier ist eine Abfrage, die Ihr Problem für Sie lösen kann:
SELECT a1.* , a1.incoming_time AS maxtime
FROM ticket t JOIN article a1 ON (t.id = a1.ticket_id)
LEFT OUTER JOIN article a2 ON (t.id = a2.ticket_id
AND a1.incoming_time < a2.incoming_time)
WHERE t.queue_id = 1
AND a2.ticket_id IS NULL;
Suchen Sie also nach einer Zeile (a1
), für die es keine andere Zeile gibt (a2
) mit derselben ticket_id
und eine größere incoming_time
. Wenn nicht größer incoming_time
gefunden wird, gibt der LEFT OUTER JOIN NULL statt einer Übereinstimmung zurück.