我有两张桌子:
tZipCodeNoCity
与ZipCode
和PointGeography
和MBLPosition
Latitude
和Longitude
在这个查询中,我找到了最接近我的位置的ZipCode。它是“穷人”地理编码:)
如何编写此查询,以便我不必执行此操作SELECT TOP 1
内联?
甚至150台设备(如20秒)也很慢
我必须在此子选项中包含150英里的半径以加快速度
SELECT LastPositions.DeviceId, P.Description, P.Latitude, P.Longitude, P.Speed, P.DeviceTime,
(
SELECT TOP 1 ZC.ZipCode
FROM dbo.tZipCodeNoCity ZC
WHERE ZC.PointGeography.STDistance(geography::STPointFromText('POINT(' + CAST(P.Longitude AS VARCHAR(20)) + ' ' + CAST(P.Latitude AS VARCHAR(20)) + ')', 4326)) < 150 * 1609.344
ORDER BY ZC.PointGeography.STDistance(geography::STPointFromText('POINT(' + CAST(P.Longitude AS VARCHAR(20)) + ' ' + CAST(P.Latitude AS VARCHAR(20)) + ')', 4326))
)
FROM dbo.MBLPosition P
INNER JOIN
(
SELECT D.DeviceId, MAX(P.PositionKey) LastPositionKey
FROM dbo.MBLPosition P
INNER JOIN IDATTApplication.dbo.MBLDevice D ON P.DeviceKey = D.DeviceKey
GROUP BY D.DeviceId
) LastPositions ON P.PositionKey = LastPositions.LastPositionKey
答案 0 :(得分:0)
在我大约12年前开展的一个项目中,我沿着这些方向运行了一个查询,以便在进行实际距离计算之前减少可能性列表:
WHERE zip.lat < my.lat + 0.5 && zip.lat > my.lat - 0.5
&& zip.long < my.long + 0.5 && zip.long > my.long - 0.5
从该子集中,我计算两点之间的实际距离并对其进行排序。你必须适当调整“0.5”部分,以获得一个足够大的盒子,以确保你会受到打击。
我认为有一种比STPointFromText
更好的方法来创建你的点对象。你能用STPointFromWKB
吗?你可以转换为geography
类型一次吗?
有关通过SET
创建积分的示例,请参阅this page。
DECLARE @p geography;
SET @p = geography::STGeomFromText('POINT(' + CAST(P.Longitude AS VARCHAR(20)) + ' ' + CAST(P.Latitude AS VARCHAR(20)) + ')', 4326);
SELECT TOP 1 ZC.ZipCode
FROM dbo.tZipCodeNoCity ZC
WHERE ZC.PointGeography.STDistance(@p)) < 150 * 1609.344
ORDER BY ZC.PointGeography.STDistance(@p))