3

我有两张桌子:

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

视频

1, 2012-01-01 12:00, 2012-01-01 12:30, A, 1.mpg
2, 2012-01-01 13:00, 2012-01-01 13:30, A, 2.mpg 
3, 2012-01-01 12:00, 2012-01-01 12:30, B, 3.mpg

结果(EventID、VideoID、文件名、IsBetween、SecondsDifference)

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 

奖金

如果最近的视频没有考虑到记录器,我会更好(但第一个边界(开始和结束)检查考虑到它)如果这太难了,那很好。

4

2 回答 2

2

这有点笨拙,但这是我想出的:

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 行,但现在,我放入 GROUP BY 以仅选择一个。

让我知道它是如何工作的。

于 2012-06-14T06:11:01.197 回答
2

我的最终结果是:

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为空的事件。

它产生与赞恩的答案相同的结果。

非常感谢赞恩。

于 2012-06-14T08:41:30.433 回答