我有一张桌子,上面有商店的清单,大约有100个经纬度。第二个表中有一个客户列表,经/纬度超过50万。
我需要找到离每个客户最近的商店。目前,我正在将地理数据类型与STDistance函数一起使用,以计算两个点之间的距离。这个功能运行良好,但是我迷上了处理此问题的最有效方法。
选项#1-笛卡尔将Customer_table加入到Store_table,处理距离计算,对结果进行排名并过滤为#1。与此相关的是,如果您有100万行客户列表和100家商店,那么您将创建一个1亿行表,而排名函数则可能会增加负担。
选项#2-使用一些动态sql,创建一个数据透视表,该表在第一列中具有每个客户,而在随后的每一列中都具有到每个分支的计算距离。从那里,我可以取消透视,然后执行与第一个步骤相同的排名/结束功能。
示例
CUST_ID LAT LONG STORE1DIST STORE2DIST STORE3DIST
1 20.00 30.00 4.5 5.6 7.8
2 20.00 30.00 7.4 8.1 8.5
我不清楚哪种方法最有效,并且会使DBA不想找我。
感谢您的预先输入!
答案 0 :(得分:0)
您可以针对每个存储距离将数据取消旋转为多行,然后使用简单的旋转(分组依据)来获取StoreDistance的最小值。
select CUST_ID, MIN(STOREDIST) StoreDistance, MIN(STORES) StoreName
from
(select CUST_ID, LAT, LONG, STORE1DIST, STORE2DIST, STORE3DIST from Cus/*Your table*/) p
UNPIVOT
(
STOREDIST FOR STORES IN (STORE1DIST, STORE2DIST, STORE3DIST)
) as unpvt
Group by CUST_ID
这将为您提供以下结果:
CUST_ID StoreDistance StoreName
-----------------------------------
1 4.5 STORE1DIST
2 7.4 STORE1DIST
答案 1 :(得分:0)
我的工作也有类似情况。我使用这样的距离函数(返回公里,使用3960*
返回英里):
CREATE Function MySTDistance(@lat1 float, @lon1 float, @lat2 float, @lon2 float)
returns smallmoney
as
return IsNull(6373*acos((sin(radians(@lat1))*sin(radians(@lat2)))
+(cos(radians(@lat1))*cos(radians(@lat2))*cos(radians(@lon1-@lon2)))),0)
然后您通过执行以下操作来寻找最近的商店...
select C.Cust_Id
,Store_id=
(select top (1) Store_id
from Store_Table S
order by dbo.MySTDistance(S.lat, S.long, C.lat, C.long)
)
from Customer_Table C
现在,您有了每个客户ID及其最接近的商店ID。拥有大量客户的速度相当快(至少就我而言)。