【问题标题】:Match Datetime entries against table with multiple time ranges将日期时间条目与具有多个时间范围的表匹配
【发布时间】:2013-10-07 10:39:36
【问题描述】:

我再次尝试解决一个与 MYSQL 相关的问题,这个问题起初听起来很简单,但现在让我有些头疼。我已经阅读了许多 sn-ps 并进行了几天的试验,但遗憾的是我在找到完美解决方案方面没有取得太大成功。

我有两张桌子。第一个包含电话,每个电话由第一个表中的一行表示,其中包含以下三列:

p_key (INT)、call_date (DATE)、call_time (TIME)

我的第二个表包含特定事件,也包含三列:

event_id (INT)、event_start (DATETIME)、event_end (DATETIME)

我只想计算我的第一个表(调用表)中的那些条目,这些条目不在同一日期的事件表的开始和结束之间的时间范围内。

我的主要问题是,单个日期的事件表中可能有多个条目(例如:同一天从 0800 到 1000 的事件和从 1400 到 1600 的另一个事件)。否则我可以简单地使用 BETWEEN 语法。

我想这可能会产生这种影响:

SELECT
SUM(
   CASE WHEN t1.p_key != 0  
   THEN 1 ELSE 0 END
) AS brt,
SUM(
   CASE WHEN t1.p_key != 0  
    AND t1.call_time NOT BETWEEN TIME(t2.event_start) AND TIME(t2.event_end)
   THEN 1 ELSE 0 END
) AS net


FROM call_table t1 INNER JOIN event_table t2
ON t1.call_date = DATE(t2.event_start)
WHERE t1.call_date >= '2013-09-01'
AND t1.call_date <= '2013-09-30'
GROUP BY DAY(t1.call_date)

很遗憾,这个查询没有返回任何结果。

有人能指点我一个粗略的方向吗?

附:我试图在我的帖子中找到关于如何格式化示例表数据的参考资料,但要么我是盲人,要么没有具体的参考资料。由于我已经看到格式良好的示例表数据,我知道这是可能的,因此也非常感谢您提供额外的线索。

更新 我设法得到一些输出,使用 LEFT JOIN 而不是 INNER。由于我不是 MySQL 专家,如果结果正确,我会去 - 咳嗽 - 用手数数。

【问题讨论】:

  • 那么部分匹配呢? IE。当调用时间在 event_end 之前开始,但在它之后结束? (在下一个 event_start 之前)?是匹配还是不匹配?
  • 嗨,Alma Do Mundo。谢谢你的评论。 call_time 没有开始或结束,它是一个时间点,仅表示呼叫开始的时间。所以我试图将时间点与时间范围相匹配,确定这个时间点是在时间范围之内还是之外。

标签: mysql datetime date-range


【解决方案1】:

你的查询应该是那么

SELECT 
  TIMESTAMP(call_date, call_time)
FROM 
  calls 
  LEFT JOIN events 
    ON TIMESTAMP(call_date, call_time)>event_start 
    AND timestamp(call_date, call_time)<event_end 
WHERE 
  event_start IS NULL

-看到这个fiddle

对于结果计数,只需这样做

SELECT 
  COUNT(calls.id)
FROM 
  calls 
  LEFT JOIN events 
    ON TIMESTAMP(call_date, call_time)>event_start 
    AND timestamp(call_date, call_time)<event_end 
WHERE 
  event_start IS NULL

【讨论】:

  • 秘密似乎是将日期+时间值转换为时间戳。确实美丽而简单。很棒的小提琴示例,非常感谢您的努力。
【解决方案2】:

试试这样的:

SELECT *
FROM call_table t1
WHERE NOT EXISTS (
    SELECT * FROM event_table t2
    WHERE TIMESTAMP(t1.date, t1.time) BETWEEN t2.event_start AND t2.event_end)
)

这应该会为您提供 call_table 中不位于 event_table 中任何事件开始日期和结束日期之间的所有记录。根据需要添加您自己的 where-criteria 和/或 count() 函数。

【讨论】:

  • 在试验了这个查询之后,看起来很有希望。我们这里或许有答案。我会在进行更多评估后报告。已经很欣赏了。
  • 很高兴听到这个消息。如果您希望我进一步详细说明这种方法,请告诉我,或者查看 MySQL EXISTS 上的文档:dev.mysql.com/doc/refman/5.0/en/…
  • @all:我已经在我的应用程序中实现了查询,它似乎可以完美地工作。再次感谢所有相关方,这个问题可以被视为已回答。不确定一个模组是否可以相应地标记它。如果可以的话,我会投票赞成这两个建议。
猜你喜欢
  • 2017-05-26
  • 2021-07-13
  • 1970-01-01
  • 1970-01-01
  • 2018-04-08
  • 1970-01-01
  • 1970-01-01
  • 2023-01-10
  • 1970-01-01
相关资源
最近更新 更多