我需要确定在给定的日期范围内每辆汽车某条路线行驶了多少次,但是基于数据库的GPS管理软件没有此功能。
该数据库包含几个表,这些表存储GPS,路线和位置数据。一条路线由几个位置和一个序列号组成。位置是一组附加在名称上的上下界纬度/经度值。车辆每分钟几次将其GPS位置数据上载到服务器,服务器会更新GPS表。
例如。某个路线“ FOO”可以依次包括位置“仓库”,“学校”,“体育场”和“公园”。“
BAR”本质上是同一条路线,但方向相反(可能在几条不同的路线上找到位置)。
一个简单的选择即可从GPS数据表中返回此类信息(车辆ID,位置,日期时间):
34 Warehouse 2011-03-26 18:17:50.000
34 Warehouse 2011-03-26 18:18:30.000
34 Warehouse 2011-03-26 18:19:05.000
34 School 2011-03-26 18:21:34.000
34 School 2011-03-26 18:21:59.000
34 School 2011-03-26 18:22:42.000
34 School 2011-03-26 18:23:55.000
34 Stadium 2011-03-26 18:24:20.000
34 Stadium 2011-03-26 18:24:47.000
34 Park 2011-03-26 18:25:30.000
34 Park 2011-03-26 18:26:50.000
34 Warehouse 2011-03-26 18:28:50.000
等等。
从手动检查中可以明显看出,车辆34当天至少走过“ FOO”路线。如何使用SQL确定当天每辆车经过该路线的总次数?
我感觉到我将不得不使用某种控制中断结构,但我希望有一种更简单的方法。这是用于从GPS表检索信息的SQL。
SELECT
v.VehicleID,
ml.LocationName
gps.Time,
FROM dbo.Routes r
INNER JOIN dbo.RoutePoints rp
ON r.RouteId = rp.RouteId
INNER JOIN dbo.MapLocations ml
ON rp.LocationId = ml.LocationId
INNER JOIN dbo.GPSData gps
ON ml.LowerRightLatitude < gps.Latitude AND ml.UpperLeftLatitude > gps.Latitude
AND ml.UpperLeftLongitude < gps.Longitude AND ml.LowerRightLongitude > gps.Longitude
INNER JOIN dbo.Vehicles v
ON gps.VehicleID = v.VehicleID
WHERE r.Desc = @routename
AND gps.Time BETWEEN @startTime AND @endTime
ORDER BY v.VehicleId, gps.Time
编辑:回溯不被视为同一路线的一部分。 仓库,学校,体育场,公园仓库,学校,体育场,公园 。FOO路线只有两次旅行。如果某个位置的偏离不属于
已知路线, 例如 仓库,学校,体育场,酒吧,公园 ,则可以忽略该位置。(即,仍然将其视为路线“ FOO”)
DECLARE @route
TABLE
(
route INT NOT NULL,
step INT NOT NULL,
destination INT NOT NULL,
PRIMARY KEY (route, step)
)
INSERT
INTO @route
VALUES
(1, 1, 1),
(1, 2, 2),
(1, 3, 3),
(1, 4, 4),
(2, 1, 3),
(2, 2, 4)
DECLARE @gps
TABLE
(
vehicle INT NOT NULL,
destination INT NOT NULL,
ts DATETIME NOT NULL
)
INSERT
INTO @gps
VALUES
(1, 1, '2011-03-30 00:00:00'),
(1, 2, '2011-03-30 00:00:01'),
(1, 1, '2011-03-30 00:00:02'),
(1, 3, '2011-03-30 00:00:03'),
(1, 3, '2011-03-30 00:00:04'),
(1, 3, '2011-03-30 00:00:05'),
(1, 4, '2011-03-30 00:00:06'),
(1, 1, '2011-03-30 00:00:07'),
(1, 3, '2011-03-30 00:00:08'),
(1, 4, '2011-03-30 00:00:09'),
(1, 1, '2011-03-30 00:00:10'),
(1, 2, '2011-03-30 00:00:11'),
(1, 2, '2011-03-30 00:00:12'),
(1, 3, '2011-03-30 00:00:13'),
(1, 3, '2011-03-30 00:00:14'),
(1, 4, '2011-03-30 00:00:15'),
(1, 3, '2011-03-30 00:00:16'),
(1, 4, '2011-03-30 00:00:17')
;
WITH iteration (vehicle, destination, ts, route, edge, step, cnt) AS
(
SELECT vehicle, destination, ts, route, 1, step, cnt
FROM (
SELECT g.vehicle, r.destination, ts, route, step, cnt,
ROW_NUMBER() OVER (PARTITION BY route, vehicle ORDER BY ts) rn
FROM (
SELECT *, COUNT(*) OVER (PARTITION BY route) cnt
FROM @route
) r
JOIN @gps g
ON g.destination = r.destination
WHERE r.step = 1
) q
WHERE rn = 1
UNION ALL
SELECT vehicle, destination, ts, route, edge, step, cnt
FROM (
SELECT i.vehicle, r.destination, g.ts, i.route, edge + 1 AS edge, r.step, cnt,
ROW_NUMBER() OVER (PARTITION BY i.route, g.vehicle ORDER BY g.ts) rn
FROM iteration i
JOIN @route r
ON r.route = i.route
AND r.step = (i.step % cnt) + 1
JOIN @gps g
ON g.vehicle = i.vehicle
AND g.destination = r.destination
AND g.ts > i.ts
) q
WHERE rn = 1
)
SELECT route, vehicle, MAX(edge / cnt)
FROM iteration
GROUP BY
route, vehicle
在这里,我们有两条路线:(1, 2, 3, 4)
和(3, 4)
车辆在途中行驶了2次,在途中行驶了(1, 2, 3, 4)
4次(3, 4)
。
重要的是,每个路由具有编号从开始的步骤1
和无间隙(虽然如果不是的话,你可以很容易地解决它使用附加CTE
有ROW_NUMBER()
)
我试图解决一个问题,但没有成功。 我有两张号码单 我有一张桌子 现在我需要计算多少次从第二个列表的数字后从第一个列表的数字,但我应该只计算一个一个id 在上面的示例表中,结果应该是2 三个匹配的pars,但是因为我们只有两个不同的ID,结果是2而不是3 PAR: 笔记我使用MSSQL 编辑。还有一列确定顺序的日期 Edit2-解决方案 我写这个查询 在这之后,我计划按id分组,每个id只使用一个匹
我有一个简单的国家/地区表,其中包含名称,大陆,人口和其他一些字段。 我正在尝试使用ActiveRecord执行以下MySQL查询 选择来自大陆=“亚洲”的国家/地区的计数(*),总和(人口),AVG(人口) 我该怎么做? 我试过: 国其中(:大陆= 国其中(:大陆= 国其中(:大陆= 它们都单独工作得很好,它们都返回数字(不是一个ActiveRelation对象),这意味着您不能做类似 国其中(
问题内容: 这个问题已经在这里有了答案 : 列数 (5个答案) 6年前关闭。 如何使用SQL计算表中的列数? 我正在使用Oracle 11g 请帮忙。t。 问题答案: 可以使用低位函数代替大写。例如:从user_tab_columns中选择count(*),其中lower(table_name)=’table_name’;
我想在我的应用程序中显示三个月,但我不知道如何显示,请帮助我如何做,这是我的代码为星期显示。谢谢你 @override protected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(r.layout.main_display);
问题内容: 使用Java访问系统时钟的简便方法是什么,以便我可以计算事件的经过时间? 问题答案: 我会避免使用它来测量经过时间。返回“壁钟”时间,该时间可能会更改(例如:夏时制,管理员用户更改时钟)并会使您的间隔测量值偏斜。 另一方面,返回自“某个参考点”(例如,JVM启动)以来的纳秒数,因此不会受到系统时钟变化的影响。
问题内容: 我需要做类似的事情: 除了,我还需要检索的前20个值的移动平均值。 首选标准SQL,但如有必要,我将使用MySQL扩展。 问题答案: 这只是我的头顶,而且我正要出门,所以未经测试。我也无法想象它会在任何种类的大数据集上表现出色。我确实确认它至少可以正常运行。:)