Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MySQL get the nearest future date to given date, from the dates located in different table having Common ID

Tags:

sql

join

mysql

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

sqlfiddle

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
like image 848
kanudo Avatar asked Feb 05 '16 18:02

kanudo


1 Answers

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

like image 172
Stidgeon Avatar answered Jan 06 '23 23:01

Stidgeon