我有两张桌子 - 客户端和宴会
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
要生成的结果是
1。未来的日期:当前日期的CLOSEST或EQUAL,与相应的客户进一步相关,应按照所需结果中给出的格式进行过滤和排序
当前案例的CURDATE()是5.2.2016
失败:查询逻辑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
失败:查询逻辑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
更新:要生成的更多结果是
2。客户端没有:DATED也应列出:可能带有NULL
3。 BANQUET表格中除DATED之外的其他信息也需要列出
更新所需结果
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
答案 0 :(得分:2)
对于此查询,我建议您应用WHERE
条件>= CURDATE()
,然后SELECT
应用MIN(dated)
GROUP BY client_id
:
SELECT b.client_id, MIN(b.dated) FROM banquet b
WHERE b.dated >= CURDATE()
GROUP BY b.client_id;
从此,您可以将必要的JOIN
添加到客户端表以获取客户端名称:
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
编辑反映新问题:
根据您添加的新信息 - 询问如何处理空值和“用餐”#39;专栏,我做了一些改变。此更新的查询处理过时的可能空值(通过调整WHERE子句),还包括膳食信息。
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;
或者你可以采取一些方法并将其与Gordon Linoff的答案结合起来,这听起来总体上会表现得更好。
新SQLFiddle:http://sqlfiddle.com/#!9/a4055/2
答案 1 :(得分:2)
一种方法使用相关子查询:
select c.*,
(select max(dated)
from banquet b
where b.client_id = c.id and
b.dated >= CURDATE()
) as dated
from client c;
然后,我会建议banquet(client_id, dated)
上的索引。
这种方法的优点是性能。它不需要在整个客户端表上进行聚合。实际上,相关子查询可以利用索引,因此查询应该具有良好的性能。
答案 2 :(得分:1)
试试这个
SELECT banquet.client_id, MIN(banquet.dated)
FROM banquet
WHERE banquet.dated >= CURDATE()
GROUP BY banquet.client_id;
如果您希望限制输出,就像您预期的结果是3记录,那么您可以在这种情况下使用limit
SELECT banquet.client_id, MIN(banquet.dated)
FROM banquet
WHERE banquet.dated >= CURDATE()
GROUP BY banquet.client_id limit 3;
如果您想使用Client
表连接,可以使用`join'
SELECT banquet.client_id, MIN(banquet.dated)
FROM banquet JOIN Client
ON Client.id = banquet.client_id
WHERE banquet.dated >= CURDATE()
GROUP BY banquet.client_id;
也会在最后一次查询中使用limit
。
答案 3 :(得分:1)
与当前日期相近或等于的日期
为了满足您的要求,我。即“CLOSEST”可能是在当前日期之前或之后,查询必须使用它与DATED
值之间的(绝对)差异。
所以可以这样实现:
SELECT
c.id, c.name, b.dated,
MIN(ABS(TIMESTAMPDIFF(DAY, b.dated, CURDATE()))) AS `delta`
FROM banquet AS b
INNER JOIN client AS c ON b.client_id = c.id
GROUP BY b.client_id
以下是SQL fiddle
答案 4 :(得分:0)
尝试: ORDER BY(ABS(DATEDIFF(row_date,NOW()))AND row_date> = NOW())DESC