Mysql SQL连接表在开始和结束之间的时间
我有两张桌子:Mysql SQL连接表在开始和结束之间的时间,mysql,sql,closest,Mysql,Sql,Closest,我有两张桌子: Events (ID, Name, Time, Recorder) Video (ID, StartTime, EndTime, Recorder, Filename) 我希望将事件数据加入到视频数据中,以便为每个事件获取视频文件名。记录器字段用于指定事件发生时可操作的记录器,并协助多个记录器同时录制视频 如果我不关心没有视频的事件,那么这很好,我可以得到SQL,但是在我的例子中,我希望显示最接近的视频文件名和秒数差 编辑 样本数据 事件 1, EV1, 2012-01-01
Events (ID, Name, Time, Recorder)
Video (ID, StartTime, EndTime, Recorder, Filename)
我希望将事件数据加入到视频数据中,以便为每个事件获取视频文件名。记录器字段用于指定事件发生时可操作的记录器,并协助多个记录器同时录制视频
如果我不关心没有视频的事件,那么这很好,我可以得到SQL,但是在我的例子中,我希望显示最接近的视频文件名和秒数差
编辑
样本数据
事件
1, EV1, 2012-01-01 12:00, A
2, EV2, 2012-01-01 13:00, B
3, EV3, 2012-01-01 12:15, B
4, EV4, 2012-01-01 11:45, A
录像带
结果
EventID、VideoID、文件名、IsBetween、秒差异
1, 1, 1.mpg, TRUE, 0
2, 3, 3.mpg, FALSE, 1800 //1800 seconds from the end of video 3
3, 3, 3.mpg, TRUE, 900
4, 1, 1.mpg, FALSE, 900 //900 seconds from the start of video 1
奖金
如果最近的视频没有考虑到录像机,而是考虑到第一个边界开始和结束检查,我会更好。如果这太难,那就好了。有点笨重,但我想到了以下几点:
SELECT
*
FROM
(
SELECT
a.ID AS EventID,
b.ID AS VideoID,
b.Filename,
(
CASE
WHEN a.Time < b.StartTime THEN UNIX_TIMESTAMP(b.StartTime) - UNIX_TIMESTAMP(a.Time)
WHEN a.Time > b.EndTime THEN UNIX_TIMESTAMP(a.Time) - UNIX_TIMESTAMP(b.EndTime)
END
) AS distance_factor
FROM
`Events` a
CROSS JOIN
video b
WHERE
NOT EXISTS
(
SELECT NULL
FROM Video
WHERE a.Time BETWEEN StartTime AND EndTime
)
) c
WHERE
c.distance_factor =
(
SELECT
MIN(CASE WHEN d.Time < e.StartTime THEN UNIX_TIMESTAMP(e.StartTime) - UNIX_TIMESTAMP(d.Time) WHEN d.Time > e.EndTime THEN UNIX_TIMESTAMP(d.Time) - UNIX_TIMESTAMP(e.EndTime) END)
FROM
`Events` d
CROSS JOIN
video e
WHERE d.ID = c.EventID
)
GROUP BY
c.EventID
这将返回日期不在任何视频的任何时间范围内的事件,然后返回最接近该事件日期的视频
现在唯一的问题是有些视频的秒差是完全相同的。我不知道您是否希望它返回2行,但现在,我在groupby中输入一行,只选择一行
让我知道它是如何工作的。我的最终结果是:
SELECT * FROM
(SELECT * FROM
(SELECT * FROM
(SELECT *, (CASE WHEN Time < StartTime THEN UNIX_TIMESTAMP(StartTime) - UNIX_TIMESTAMP(Time)
WHEN Time > EndTime THEN UNIX_TIMESTAMP(Time) - UNIX_TIMESTAMP(EndTime)
END
) AS SecondsDifference
FROM
(
SELECT * FROM Events E
LEFT JOIN Video V ON (E.Time >= V.StartTime AND E.Time <= V.EndTime)
WHERE DVID IS NULL GROUP BY E.EventID
) A ORDER BY A.EventID, A.SecondsDifference
) B GROUP BY EventID
) C WHERE C.SecondsDifference IS NOT NULL
从本质上说,这首先获取没有任何视频的所有事件,然后将此结果加入整个视频列表,按EventID和ClosestSeconds排序,然后按EventID对结果进行分组以删除重复项。最后,我需要删除SecondsDifference为null的所有事件
它产生的结果与赞恩的答案相同
非常感谢Zane。您能提供样本数据和预期结果吗?startTime、EndDateTime和Time字段是否同时包含日期和时间?是否应根据输入时间是否接近startTime或endtime返回该字段?另外,视频字段中的ID是否引用了事件表中的ID字段?@Zane Bien-它应该只返回从开始或结束到最近的视频文件,不,ID在两个表之间没有链接,明白吗!我看看能想出什么办法。我喜欢这样的挑战。哦,顺便问一下,会不会有一个活动直接在视频日期范围之间?i、 e.“2012-01-01 12:15”如果是的话,它是否应该返回它与开始日期之间的差值(如果它更接近开始日期),而结束日期是否应该返回它与开始日期之间的差值?@Zane Bien,是的,可能存在介于日期范围之间的事件。在这种情况下,我唯一的要求是我需要区分视频时间和外部时间之间的事件。如果需要,可能会返回一个IsBetween字段+1谢谢-这确实会产生正确的输出,但是关于clunky:,您是对的。我设法对它进行了一些优化,速度快了10倍左右
SELECT * FROM
(SELECT * FROM
(SELECT * FROM
(SELECT *, (CASE WHEN Time < StartTime THEN UNIX_TIMESTAMP(StartTime) - UNIX_TIMESTAMP(Time)
WHEN Time > EndTime THEN UNIX_TIMESTAMP(Time) - UNIX_TIMESTAMP(EndTime)
END
) AS SecondsDifference
FROM
(
SELECT * FROM Events E
LEFT JOIN Video V ON (E.Time >= V.StartTime AND E.Time <= V.EndTime)
WHERE DVID IS NULL GROUP BY E.EventID
) A ORDER BY A.EventID, A.SecondsDifference
) B GROUP BY EventID
) C WHERE C.SecondsDifference IS NOT NULL