Mysql 棘手的SQL查询-需要获取时间框架
我偶然发现了一个问题,当我需要一个查询,它将生成一个加速时间框架的列表 下面是数据示例Mysql 棘手的SQL查询-需要获取时间框架,mysql,tsql,Mysql,Tsql,我偶然发现了一个问题,当我需要一个查询,它将生成一个加速时间框架的列表 下面是数据示例 [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/201
[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
现在,我尝试了什么?我试着把它放在单独的表、查询和一些连接中。。。什么都不管用,我很沮丧。。。我甚至不确定这是否可以通过查询实现。寻求专家的帮助 您是否尝试过这样的方法,忽略了平均速度计算:
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
这会给你带来很多重叠的时间框架,不确定这是否是你想要的。如果不存在,则可以使用“不存在”进行筛选:
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,一个从19:00到19:07,另一个从19:03到19:10
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且IntervalCheck=1的所有行删除,最后可以使用聚合函数和CASE查找RowNumber为1的行(第一行超速),或该间隔的最高RowNumber(最后一行超速)。最后的连接只是重复这个过程,以找到每个intervalID的最大行数
你能不能更具体地说一下你想总结什么?为什么当您的输入表每分钟有18:53到19:10的时间时,摘要输出只有三行19:00-19:02、19:03-19:05和19:10-19:10?你的lat和long值真的是整数吗?您的输入表应该是某种GPS轨迹,显示时间、位置和速度。关于你的问题的任何细节都会有帮助。我想我忘了提到它应该显示速度超过80帧。你能做一个sqlfiddle吗?根据您所描述的,您需要执行一个分组