1

高速化された時間枠のリストを生成するクエリが必要なときに、問題に遭遇しました。

データ例はこちら

[idgps_unit_location]   [dt]    [idgps_unit]    [lat]   [long]  [speed_kmh]
26  10/18/2012 18:53    2   47  56  30
27  10/18/2012 18:53    2   49  58  31
28  10/18/2012 18:53    2   28  37  15
29  10/18/2012 18:54    2   56  65  33
30  10/18/2012 18:54    2   152 161 73
31  10/18/2012 18:55    2   134 143 64
32  10/18/2012 18:56    2   22  31  12
36  10/18/2012 18:59    2   98  107 47
37  10/18/2012 18:59    2   122 131 58
38  10/18/2012 18:59    2   91  100 44
39  10/18/2012 19:00    2   190 199 98
40  10/18/2012 19:01    2   194 203 101
41  10/18/2012 19:02    2   182 191 91
42  10/18/2012 19:03    2   162 171 78
43  10/18/2012 19:03    2   174 183 83
44  10/18/2012 19:04    2   170 179 81
45  10/18/2012 19:05    2   189 198 97
46  10/18/2012 19:06    2   20  29  10
47  10/18/2012 19:07    2   158 167 76
48  10/18/2012 19:08    2   135 144 64
49  10/18/2012 19:08    2   166 175 79
50  10/18/2012 19:09    2   9   18  5
51  10/18/2012 19:09    2   101 110 48
52  10/18/2012 19:09    2   10  19  7
53  10/18/2012 19:10    2   32  41  20
54  10/18/2012 19:10    1   54  63  85
55  10/19/2012 19:11    2   55  64  50

このテーブルを、速度が 80 を超える時間のフレームを示す次のレポートに変換するクエリが必要です。

[idgps_unit]    [dt_start]  [lat_start] [long_start]    [speed_start]   [dt_end]    [lat_end]   [long_end]  [speed_end] [speed_average]
2   10/18/2012 19:00    190 199 98  10/18/2012 19:02    182 191 91  96.66666667
2   10/18/2012 19:03    174 183 83  10/18/2012 19:05    189 198 97  87
1   10/18/2012 19:10    54  63  85  10/18/2012 19:10    54  63  85  85

さて、私は何を試しましたか?これを別のテーブル、クエリに入れてみましたが、いくつかの結合を実行しました...何も機能せず、非常にイライラしています...クエリを介してこれを実行できるかどうかさえわかりません。専門家の助けを求める!

4

2 に答える 2

3

あなたは正しかった、それはかなりトリッキーです、しかし私はそれを管理したと思います:

SELECT  s.idgps_unit,
        MIN(s.dt) AS DT_Start,
        MIN(CASE WHEN s.RowNumber = 1 THEN s.Lat END) AS Lat_Start,
        MIN(CASE WHEN s.RowNumber = 1 THEN s.Long END) AS Long_Start,
        MIN(CASE WHEN s.RowNumber = 1 THEN s.Speed_kmh END) AS Speed_Start,
        MAX(s.dt) AS dt_end,
        MIN(CASE WHEN s.RowNumber = MaxRowNumber THEN s.Lat END) AS Lat_End,
        MIN(CASE WHEN s.RowNumber = MaxRowNumber THEN s.Long END) AS Long_End,
        MIN(CASE WHEN s.RowNumber = MaxRowNumber THEN s.Speed_kmh END) AS Speed_End,

        AVG(Speed_kmh) AS Speed_Average
FROM    (   SELECT  T.*,
                    @i:= CASE WHEN Speed_Kmh > 80 AND @b = 0 THEN @i + 1 ELSE @i END AS IntervalID,
                    @r:= CASE WHEN Speed_Kmh > 80 AND @b = 0 THEN 1 ELSE @r + 1 END AS RowNumber,
                    @b:= CASE WHEN Speed_Kmh> 80 THEN 1 ELSE 0 END AS IntervalCheck
            FROM    T,
                    (SELECT @i:= 0) i,
                    (SELECT @r:= 0) r,
                    (SELECT @b:= 0) b
            ORDER BY dt, idgps_unit_location
        ) s
        INNER JOIN
        (   SELECT  IntervalID, MAX(RowNumber) AS MaxRowNumber
            FROM    (   SELECT  T.*,
                                @i:= CASE WHEN Speed_Kmh > 80 AND @b = 0 THEN @i + 1 ELSE @i END AS IntervalID,
                                @r:= CASE WHEN Speed_Kmh > 80 AND @b = 0 THEN 1 ELSE @r + 1 END AS RowNumber,
                                @b:= CASE WHEN Speed_Kmh> 80 THEN 1 ELSE 0 END AS IntervalCheck
                        FROM    T,
                                (SELECT @i:= 0) i,
                                (SELECT @r:= 0) r,
                                (SELECT @b:= 0) b
                        ORDER BY dt, idgps_unit_location
                    ) d
            WHERE   IntervalCheck = 1
            GROUP BY IntervalID
        ) MaxInt
            ON MaxInt.IntervalID = s.IntervalID
WHERE   s.IntervalCheck = 1
GROUP BY s.IntervalID, s.idgps_unit;

重要なのはこの部分です。

SELECT  T.*,
        @i:= CASE WHEN Speed_Kmh > 80 AND @b = 0 THEN @i + 1 ELSE @i END AS IntervalID,
        @r:= CASE WHEN Speed_Kmh > 80 AND @b = 0 THEN 1 ELSE @r + 1 END AS RowNumber,
        @b:= CASE WHEN Speed_Kmh> 80 THEN 1 ELSE 0 END AS IntervalCheck
FROM    T,
        (SELECT @i:= 0) i,
        (SELECT @r:= 0) r,
        (SELECT @b:= 0) b
ORDER BY dt, idgps_unit_location

速度が超過している行に遭遇するたびに、変数@bを1に設定します。この変数が、行に新しいintervalIDを割り当てる前に0だった場合、これを行うと、行に再び1の番号が付けられるため、終了します。このようなものでアップ:

[idgps_unit_location]   [dt]                [idgps_unit]    [lat]   [long]  [speed_kmh] [IntervalID]    RowNumber   IntervalCheck
37                      10/18/2012 18:59    2               122     131     58          1               1           0
38                      10/18/2012 18:59    2               91      100     44          1               2           0
39                      10/18/2012 19:00    2               190     199     98          2               1           1
40                      10/18/2012 19:01    2               194     203     101         2               2           1
41                      10/18/2012 19:02    2               182     191     91          2               3           1
42                      10/18/2012 19:03    2               162     171     78          2               4           0
43                      10/18/2012 19:03    2               174     183     83          3               1           1

次に、速度が80未満(WHERE IntervalCheck = 1)のすべての行を削除する必要があります。最後に、集計関数とCASEを使用して、RowNumber1(速度の最初の行)またはその間隔(スピード違反の最後の行)。最後の結合は、単にプロセスを繰り返して、各intervalIDの最大行番号を見つけます。

SQLフィドルの例

于 2012-10-31T23:21:27.870 に答える
0

このようなことを試しましたか(平均速度の計算を省略):

SELECT * FROM (
SELECT
   start.idgps_unit,
   start.dt dt_start,
   ...
   end.dt dt_end,
   ...
   (...) average_speed
FROM
   your_table start,
   your_table end
WHERE
   start.dt < end.dt
)
WHERE average_speed > 80

これにより、多くの重複する時間枠が得られますが、これが望ましいかどうかはわかりません. そうでない場合は、NOT EXISTS でフィルタリングできます。

SELECT *
FROM (query_above) timeframes
WHERE NOT EXISTS (
SELECT *
FROM (query_above) longer_timeframes
WHERE 
   longer_timeframes.dt_start < timeframes.dt_end OR
   longer_timeframes.dt_end > timeframes.dt_end
)

たとえば、19:00 から 19:03 までは 60、19:03 から 19:07 までは 100、19:07 から 19:10 までは 60 とします。次に、平均速度が 80 を超えた最長時間間隔が 2 つあり、1 つは 19:00 から 19:07 まで、もう 1 つは 19:03 から 19:10 までです。

于 2012-10-31T22:48:01.560 に答える