This is the classic hurdle most MySQL programmers face.
- You have a
ticket_id column, which is a GROUP BY argument. The individual values ββin this column define the groups. - You have an
incoming_time column, which is the argument to MAX() . The largest value in this column by row in each group is returned as the value of MAX() . - You have all the other columns in the table. The values ββreturned for these columns are arbitrary, not from the same row as the
MAX() value.
The database cannot indicate that you need values ββfrom the same row where the maximum value takes place.
Consider the following cases:
There are several lines in which the same maximum value occurs. Which row should be used to display article.* Columns?
You are writing a query that returns both MIN() and MAX() . This is legal, but which line should article.* Show?
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
You are using an aggregate function such as AVG() or SUM() , where not a single line has this value. How does the database guess which row to display?
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 most brands of the database, as well as the SQL standard itself, you are not allowed to write such a query because of ambiguity. You cannot include a single column in a selection list that is not inside an aggregate function or named in a GROUP BY .
MySQL is more permissive. It allows you to do this and leaves you the opportunity to write queries without ambiguity. If you have ambiguity, it selects the values ββfrom the row that is physically the first in the group (but this depends on the storage mechanism).
For what it's worth, SQLite also has this behavior, but it selects the last row in the group to eliminate ambiguity. Go figure. If the SQL standard does not say what to do, it depends on the implementation of the provider.
Here is a request that may solve your problem for you:
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;
In other words, find line ( a1 ) for which there is no other line ( a2 ) with the same ticket_id and large incoming_time . If no more incoming_time found, the LEFT OUTER JOIN returns NULL instead of a match.
Bill karwin
source share