MySQL从位于具有公共ID的不同表中的日期中获取最近的未来日期到给定日期
Posted
技术标签:
【中文标题】MySQL从位于具有公共ID的不同表中的日期中获取最近的未来日期到给定日期【英文标题】:MySQL get the nearest future date to given date, from the dates located in different table having Common ID 【发布时间】:2016-02-05 18:00:46 【问题描述】:我有两张桌子 - Client 和 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
要生成的结果是这样的
1. 未来的日期:接近或等于当前日期,与相应客户进一步相关的日期应按
所需结果中给出的格式进行过滤和排序强> 当前案例的 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
sqlfiddle
UPDATE :要生成的进一步结果是这样的
2. 客户 WITHOUT : 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
【问题讨论】:
“饭”从何而来?鉴于您在回答问题后对问题进行了重大更改,您可能希望针对“NULL”案例和“膳食”组件发布一个单独的问题。 @Stidgeon 我也很困惑,我应该在同一个问题还是在新问题中问这个问题。但现在我认为新问题是一个好方法.. 【参考方案1】:对于这个查询,我建议应用你的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
编辑以反映问题的新部分:
根据您添加的新信息 - 询问如何处理空值和“用餐”列,我进行了一些更改。此更新后的查询处理日期中可能的空值(通过调整 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
【讨论】:
它工作得很好,而且它还可以通过在SELECT
中提及来获取两个表中的任何字段。但它不能给CLIENTS
和BANQUET.DATED
havin NULL
。好吧,这不是我最初的问题,但我改进并更新了同样的问题。【参考方案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)
的索引。
这种方法的优点是性能。它不需要对整个客户端表进行聚合。事实上,相关子查询可以利用索引,所以查询应该有很好的性能。
【讨论】:
当只有banquet.dated
被作为banquet
的输出时,它的工作非常棒。但是,当我尝试为输出获取banquet.meal
时,它不起作用。好吧,这不是我最初的问题,但我更新了同样的问题。【参考方案3】:
试试这个
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,你可以使用`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
。
【讨论】:
【参考方案4】:与当前日期最接近或等于的日期
为了密切响应您的要求,我。 e. “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
【讨论】:
@Stidgeon 是的,现在我明白了。但是问题已被修改,只是添加了“未来”(查看编辑 1),可能是当 OP 阅读我的答案并意识到问题不明确时。 @cFreed 这也不是我的确切问题,但它对我的其他查询有所帮助,因此支持答案【参考方案5】:尝试: ORDER BY (ABS(DATEDIFF(row_date, NOW())) AND row_date>=NOW()) DESC
【讨论】:
为了让这个答案对这个问题的读者更有用,考虑添加一个描述来解释你在做什么。以上是关于MySQL从位于具有公共ID的不同表中的日期中获取最近的未来日期到给定日期的主要内容,如果未能解决你的问题,请参考以下文章