查询存在 Max(Date) 的记录

Posted

技术标签:

【中文标题】查询存在 Max(Date) 的记录【英文标题】:Query for Records Where Exists Having Max(Date) 【发布时间】:2016-03-17 03:50:26 【问题描述】:

我正在尝试创建一个查询以查找一个线程,该线程具有至少一条日期小于 20 分钟的记录

这是一个如下所示的心跳表:

+--------------+-----------+---------------------+---------------------+
| heartbeat_id | server_id | thread              | last_checkin        |
+--------------+-----------+---------------------+---------------------+
|            3 |       133 | EscalationMonitor   | 2016-03-16 23:46:07 |
|            7 |       133 | EmailMonitor        | 2016-03-16 23:47:31 |
|           11 |       133 | TableMonitor        | 2016-03-16 23:42:49 |
|           15 |       133 | NotificationMonitor | 2016-03-16 23:46:30 |
|           19 |       127 | EmailMonitor        | 2016-03-16 23:47:21 |
|           23 |       127 | TableMonitor        | 2016-03-16 23:46:11 |
|           27 |       127 | EscalationMonitor   | 2016-03-16 23:47:58 |
|           31 |       127 | NotificationMonitor | 2016-03-16 23:41:10 |
|           35 |       123 | EmailMonitor        | 2016-03-16 23:47:59 |
|           39 |       123 | TableMonitor        | 2016-03-16 23:43:10 |
|           43 |       123 | EscalationMonitor   | 2016-03-16 23:46:26 |
|           47 |       123 | NotificationMonitor | 2016-03-16 23:46:47 |
+--------------+-----------+---------------------+---------------------+

这是我所在的位置,但这会搜索至少一条超过 20 分钟的记录

SELECT * FROM heartbeat h WHERE exists
(
    select * from heartbeat h2
    where last_checkin < date_add(now(), INTERVAL - 20 MINUTE)
)
group by thread

【问题讨论】:

INTERVAL - 20 MINUTE中删除- 这意味着 last_checkin 不,它将早于创建日期后的20 分钟 假设您的记录已添加到您的表中,它们必须具有创建日期,因此这将仅检查自 20 分钟前插入的记录 现在可以说是23:59。并以EmailMonitor 为例。您当前的查询为您提供7,133,EmailMonitor, 2016-03-16 23:47:31。你对EmainMonitor 有什么期望,为什么? 【参考方案1】:

如果您希望线程在 20 分钟前至少有 1 次签入,您可以将该条件放在 where 子句中并使用 distinct 删除重复项:

select distinct thread from heartbeat
where last_checkin > date_sub(now(), INTERVAL 20 MINUTE)

要检索不到 20 分钟没有签到的所有线程:

select thread from heartbeat
group by thread
having count(case when last_checkin > date_sub(now(), INTERVAL 20 MINUTE) then 1 end) = 0

如果您有threads 表,那么您可以利用not exists

select * from threads t where not exists (
  select 1 from heartbeat h
  where t.thread = h.thread
  and h.last_checkin >  date_sub(now(), INTERVAL 20 MINUTE)
)

【讨论】:

我想要至少有 1 次签入时间小于 20 分钟的线程。换句话说,我想要没有超过 20 分钟的签到的线程。 (实际上,这将是一个监控 cron,如果结果集中有记录,它将调用警报。所以“没有少于 20 分钟的记录”将是正确的表达方式。) @JonasJSchreiber 更新了查询,但这些不一样。假设一个线程在 15 分钟前和 40 分钟前都有签到。这将满足第一个条件,但不满足第二个条件。 Yeeeess,那个查询“有 count(...) = 0”是我要找的那个。谢谢@FuzzyTree【参考方案2】:

INTERVAL - 20 MINUTE 中删除-

【讨论】:

这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review 我已经为他的问题提供了诀窍并在评论中进行了解释,然后 Fuzzy 使用我的技巧重新更正了他的第一个答案 它需要 date_sub 才能工作。我认为 date_add(now(), interval - 20 minute) 是 date_sub(now(), interval 20 minute) 的同义词。

以上是关于查询存在 Max(Date) 的记录的主要内容,如果未能解决你的问题,请参考以下文章

T-SQL 子查询 Max(Date) 和连接

为啥我的 Access Max() 子查询不起作用?

SQL SELECT MAX() 返回多条记录

SQL 查询:HAVING date = MAX(date) 不起作用

如何从 mysql 查询中存储对象 max(date) 和 min(date)

Oracle 使用 MAX 获取最新记录