Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MYSQL GROUP_CONCAT with ORDER BY strange sorting results

Tags:

sql

mysql

This is my working query, no errors, but the sorting by certain columns is strange.

$query = mysql_query("SELECT ServiceType, Location, Destination, Name, PAX,
                      TransferTime, Ticket SUM(PAX) AS TotalPAX,
                      GROUP_CONCAT( Coupon SEPARATOR '<BR>') AS PasTicket,
                      GROUP_CONCAT( TransferTime SEPARATOR '<BR>') AS PasTransferTime,
                      GROUP_CONCAT( Location SEPARATOR '<BR>') AS PasLocation,
                      GROUP_CONCAT( Destination SEPARATOR '<BR>') AS PasDestination,
                      GROUP_CONCAT( Name SEPARATOR '<BR>') AS PasName,
                      GROUP_CONCAT( PAX SEPARATOR '<BR>') AS PasPAX
                      FROM Reservations WHERE Date = '$DateToday'
                      GROUP BY Ticket
                      ORDER BY ServiceType, TransferTime ASC");

This gives me the following results which are the correct data but in wrong order:

REF | SERVICE   | TIME     | PAX | HOTEL      | FROM    | NAME            | TICKET
----+-----------+----------+-----+------------+---------+-----------------+----------------
17  | DEPARTURE | 15:00:00 | 1.0 | IBEROSTAR  | AIRPORT | FRANCIS EUGEN   | TICKET: #110588
18  | DEPARTURE | 15:20:00 | 2.0 | PARADISUS  | AIRPORT | MARTIN CIBBAR   | TICKET: #110589
19  | DEPARTURE | 16:40:00 | 2.0 | PARADISUS  | AIRPORT | JOHN CIA        | TICKET: #3376
20  | DEPARTURE | 16:00:00 | 2.0 | RIU PALACE | AIRPORT | ALAN KRAMER     | TICKET: #110589
21  | DEPARTURE | 16:10:00 | 2.0 | RIU PALACE | AIRPORT | JOHN WILLS      | TICKET: #110589
22  | DEPARTURE | 16:20:00 | 2.0 | RIU PALACE | AIRPORT | PETER LONG      | TICKET: #110589

When I GROUP BY Ticket the query works but the Times are out of order, however if I add ORDER BY Time ASC the ORDER BY does not work - GROUP BY Time does work but then I lose the GROUP BY Ticket but I cannot use GROUP BY Time anyways... Number 18, 20, 21 and 22 should be GROUPED together with Time in ORDER ASC.

The ideal would be something like: WHERE Date = '$DateToday' GROUP BY Ticket, TransferTime (LIKE '%TransferTime%') ORDER BY ServiceType, TransferTime ASC. This is because TransferTimes can differ by some minutes and GROUP BY is too strict.

Below is an example of what it should be, GROUPED BY Ticket Number and sorted by TIME ASC. I have left the REF numbers as they were to make it clearer. Strange thing is, we have this working live but in MSSQL but the system is from 2013 and we need to pass it over to MYSQL and PHP.

REF | SERVICE   | TIME     | PAX | HOTEL      | FROM    | NAME            | TICKET
----+-----------+----------+-----+------------+---------+-----------------+----------------
17  | DEPARTURE | 15:00:00 | 1.0 | IBEROSTAR  | AIRPORT | FRANCIS EUGEN   | TICKET: #110588
20  | DEPARTURE | 16:00:00 | 2.0 | RIU PALACE | AIRPORT | ALAN KRAMER     | TICKET: #110589
21  | DEPARTURE | 16:10:00 | 2.0 | RIU PALACE | AIRPORT | JOHN WILLS      | TICKET: #110589
22  | DEPARTURE | 16:20:00 | 2.0 | RIU PALACE | AIRPORT | PETER LONG      | TICKET: #110589
18  | DEPARTURE | 16:40:00 | 2.0 | PARADISUS  | AIRPORT | MARTIN CIBBAR   | TICKET: #110589
19  | DEPARTURE | 16:40:00 | 2.0 | PARADISUS  | AIRPORT | JOHN CIA        | TICKET: #3376

GROUP_CONCAT appears to be working fine. Any ideas whats going on?

Screen dump image (names and flights changed). The data is complete and correct, but the sorting order of the ticket number is off. I realize this is because I am using GROUP BY Time which is too strict because Time can vary somewhat.

PS: The GROUP_BY SEPARATOR is a line break BR which for some reason is not being published. Screen Dump

like image 797
Stray Dog Avatar asked Sep 15 '25 19:09

Stray Dog


1 Answers

Order of GROUP_CONCAT result string

You simply haven't stated an order for the group_concats, which would be

GROUP_CONCAT(... ORDER BY ...)

e.g.

GROUP_CONCAT( Coupon ORDER BY Id SEPARATOR '<BR>') AS PasTicket

so the order of your group_concats is left to chance.

Order of the rows

As to the rows, you have stated an order, but you order your result by columns that are not in your select list, so this is kind of an invisible sort. (An example for clarification: if I show a list of first and last names, but behind the scenes I order these persons by the city they live in, the names will seem unordered.)

As you group by Ticket it is also important to know whether there is exactly one ServiceType and one TransferTime per Ticket. If not, you'd get the values arbitrarily picked, which is probably undesired. (Illustration: If a ticket has rows with service types A and M and Z, one of these will be picked and it is left to chance which the DBMS picks.)

At last:

And as has been mentioned, when you aggregate (GROUP BY), but SELECT * you will get arbitrarily picked values. Say a ticket has two rows, one with DEPARTURE | 15:00:00 and one with ARRIVAL | 18:00:00, you may even end up with DEPARTURE | 18:00:00 for the ticket.

like image 96
Thorsten Kettner Avatar answered Sep 18 '25 12:09

Thorsten Kettner