3

私は2つのテーブルを持っています:

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 * 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

基本的に、これは最初にビデオなしですべてのイベントを取得し、次にこの結果をビデオリスト全体に結合し、EventIDClosestSecondsで並べ替え、次に結果をでグループ化しEventIDて重複を削除します。SecondsDifference最後に、がnullであるイベントを削除する必要がありました。

Zaneの答えと同じ結果が得られます。

どうもありがとうゼーン。

于 2012-06-14T08:41:30.433 に答える
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 行を返すようにするかどうかはわかりませんが、今のところ、1 つだけを選択するために GROUP BY を入れています。

それがどのように機能するか教えてください。

于 2012-06-14T06:11:01.197 に答える