I have two tables – Client and Banquet
Client Table ---------------------------- ID NAME 1 John 2 Jigar 3 Jiten ---------------------------- Banquet Table ---------------------------- ID CLIENT_ID DATED 1 1 2016.2.3 2 2 2016.2.5 3 2 2016.2.8 4 3 2016.2.6 5 1 2016.2.9 6 2 2016.2.5 7 2 2016.2.8 8 3 2016.2.6 9 1 2016.2.7 ---------------------------- :::::::::: **Required Result** ---------------------------- ID NAME DATED 2 Jigar 2016.2.5 3 Jiten 2016.2.6 1 John 2016.2.7
The result to be generated is such that
1. The Date which is FUTURE : CLOSEST or EQUAL to the current date, which is further related to the respective client should be filtered and ordered in format given in Required Result
CURDATE() for current case is 5.2.2016
FAILED: Query Logic 1
SELECT c.id, c.name, b.dated FROM client AS c, banquet AS b WHERE c.id = b.client_id AND b.dated >= CURDATE() ORDER BY (b.dated - CURDATE()); ------------------------------------------- OUTPUT ID NAME DATED 2 Jigar 2016.2.5 2 Jigar 2016.2.5 3 Jiten 2016.2.6 3 Jiten 2016.2.6 1 John 2016.2.7 2 Jigar 2016.2.8 2 Jigar 2016.2.8 1 John 2016.2.9
FAILED: Query Logic 2
SELECT c.id, c.name, b.dated FROM client AS c, banquet AS b WHERE b.dated = ( SELECT MIN(b.dated) FROM banquet as b WHERE b.client_id = c.id AND b.dated >= CURDATE() ) ORDER BY (b.dated - CURDATE()); ------------------------------------------- OUTPUT ID NAME DATED 2 Jigar 2016.2.5 2 Jigar 2016.2.5 3 Jiten 2016.2.6 3 Jiten 2016.2.6 1 John 2016.2.7
UPDATE : Further result to be generated is such that
2. Clients WITHOUT : DATED should also be listed : may be with a NULL
3. the information other then DATED in the BANQUET table also need to be listed
UPDATED Required Result
ID NAME DATED MEAL 2 Jigar 2016.2.5 lunch 3 Jiten 2016.2.6 breakfast 1 John 2016.2.7 dinner 4 Junior - - 5 Master - supper
Advertisement
Answer
For this query, I suggest applying your WHERE
condition >= CURDATE()
and then SELECT
the MIN(dated)
with GROUP BY client_id
:
SELECT b.client_id, MIN(b.dated) FROM banquet b WHERE b.dated >= CURDATE() GROUP BY b.client_id;
From this, you can add the necessary JOIN
to the client table to get the client name:
SELECT b.client_id, c.name, MIN(b.dated) FROM banquet b INNER JOIN client c ON c.id = b.client_id WHERE b.dated >= CURDATE() GROUP BY b.client_id;
SQLFiddle: http://sqlfiddle.com/#!9/aded8/18
EDITED TO REFLECT NEW PARTS OF QUESTION:
Based on the new info you added – asking how to handle nulls and the ‘meal’ column, I’ve made some changes. This updated query handles possible null values (by adjusting the WHERE clause) in dated, and also includes meal information.
SELECT b.client_id, c.name, MIN(b.dated) AS dated, IFNULL(b.meal, '-') AS meal FROM banquet b INNER JOIN client c ON c.id = b.client_id WHERE b.dated >= CURDATE() OR b.dated IS NULL GROUP BY b.client_id;
or you can take some of this and combine it with Gordon Linoff’s answer, which sounds like it will perform better overall.
New SQLFiddle: http://sqlfiddle.com/#!9/a4055/2