In my system, I have clients. Clients have programs. I want to display a list of clients, showing their most recent active (if it exists) program.
Thus, we have something like this:
SELECT *
FROM clients AS client
JOIN programs AS program ON client.id=program.client_id
GROUP BY client.id
ORDER BY program.close_date=0 DESC, program.close_date DESC
close_date=0
means the program isn't closed. So it will put the non-closed programs first, and then the most recently closed programs next.
Problem is, the order by doesn't work within the groups. It just kind of picks one of the programs at random. How do I resolve this?
Just came up with this:
SELECT *
FROM clients AS client
JOIN (SELECT * FROM programs AS program ORDER BY program.close_date=0 DESC, program.close_date DESC) AS program ON client.id=program.client_id
GROUP BY client.id
Which seems to give correct results. Is this correct, or am I just getting lucky? i.e., I've essentially sorted the table before joining on it; those results will stay sorted as it does the join, right?
Solution: I now believe this a classic group-wise maximum problem. Search for that if you're stuck on a similar problem. The solution involves joining the same table twice.
Using Group By and Order By Together When combining the Group By and Order By clauses, it is important to bear in mind that, in terms of placement within a SELECT statement: The GROUP BY clause is placed after the WHERE clause. The GROUP BY clause is placed before the ORDER BY clause.
In the query, GROUP BY clause is placed after the WHERE clause. In the query, GROUP BY clause is placed before ORDER BY clause if used any.
In select statement, it has to be used before the 'ORDER BY' keyword. Attribute can't be in a 'GROUP BY' statement when it is under aggregate function. The tuples are grouped based on how similar the attribute values of the tuples are. It controls the presentation of the tuples/rows.
SELECT c.*, p.*
FROM clients AS c
JOIN programs AS p
ON p.id =
(
SELECT pi.id
FROM programs AS pi
WHERE pi.client_id = c.id
ORDER BY
pi.close_date=0 DESC, pi.close_date DESC
LIMIT 1
)
Thanx should go to @Quassnoi. See his answer in a similar (but more complicated) question: mysql-group-by-to-display-latest-result
If you update the programs
table and set close_date
for all records that it is zero to close_date='9999-12-31'
, then your ORDER BY
will be simpler (and the whole query faster with proper indexes):
ORDER BY
pi.close_date DESC
Try this order by clause ...
ORDER BY client.id, CASE WHEN program.close_date = 0 THEN 0 ELSE 1 END, program.close_date DESC
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With