注册 登录
编程论坛 ACCESS论坛

如何跨表找到距离最近的点?

xiangyue0510 发布于 2019-07-31 17:17, 3388 次点击
有两个表格A、B,都记录了很多点,有X、Y坐标字段,但是两个表的记录并不一一对应,数量也不一样
A表中所有记录想要在B表中找到与之最近的点。
我用下面的语句查出来的结果明显不对,因为A表有2000条数据,结果出来只有80多条数据。正常应该是2000条。
SELECT [1].[X], [1].[Y], [2].[X], [2].[Y]
FROM 1, 2
WHERE
([1].[X]-[2].[X])*([1].[X]-[2].[X])+ ([1].[Y]-[2].[Y]) * ([1].[Y]-[2].[Y]) * 0.01*3.14*3.14/180/180 = (select min(([1].[X]-[2].[X])*([1].[X]-[2].[X])+([1].[Y]-[2].[Y]) * ([1].[Y]-[2].[Y])*0.01*3.14*3.14/180/180) FROM 1, [2]);
p.s.  上面的Y其实是角度,* 0.01*3.14*3.14/180/180就是将角度转化为弧线长度之后的计算。
1 回复
#2
wufuzhang2019-07-31 21:02
回复 楼主 xiangyue0510
select min(([1].[X]-[2].[X])*([1].[X]-[2].[X])+([1].[Y]-[2].[Y]) * ([1].[Y]-[2].[Y])*0.01*3.14*3.14/180/180) FROM [1], [2]
这一句有问题:这个语句是把表1,表2组成的新表里面,这个表达式的最小值输出,
然后你再从表1,表2组成的新表里面去查,这个表达式的值 = 这个最小值时,所对应的XY坐标,这显然是错误的。

应该先将表1,表2组成的新表(假设表3)中按照表1的编号分组,求出每个编号组的最小值及对应的编号,然后再从表3中查找,
表达式 = 最小值,且编号相等。

程序代码:

select T1.T1_1_X as "1.X", T1.T1_1_Y as "1.Y", T1.T1_2_X as "2.X", T1.T1_2_Y "2.Y"
    from (select [1].ID as "T1_ID", [1].X as "T1_1_X", [1].Y as "T1_1_Y", [2].X as "T1_2_X", [2].Y as "T1_2_Y" from [1], [2]) as "T1" ,
         (select [1].ID as "T2_ID", MIN(([1].X-[2].X)*([1].X-[2].X) + ([1].Y-[2].Y)*([1].Y-[2].Y)* 0.01*3.14*3.14/180/180 ) as "T2_Min"
          from [1], [2] group by [1].ID) as "T2"
    where (T1.T1_1_X-T1.T1_2_X)*(T1.T1_1_X-T1.T1_2_X) + (T1.T1_1_Y-T1.T1_2_Y)*(T1.T1_1_Y-T1.T1_2_Y)* 0.01*3.14*3.14/180/180 = T2.T2_Min and T1.T1_ID = T2.T2_ID


如果用内连接会更简便一点
程序代码:

select [1].X, [1].Y, [2].X, [2].Y
    from [1]
    join [2]
    on 1=1
    join (select [1].ID as "1_ID", MIN(([1].X-[2].X)*([1].X-[2].X) + ([1].Y-[2].Y)*([1].Y-[2].Y)* 0.01*3.14*3.14/180/180 ) as "miniux"
          from [1], [2] group by [1].ID) as "T"
    on ([1].X-[2].X)*([1].X-[2].X) + ([1].Y-[2].Y)*([1].Y-[2].Y)* 0.01*3.14*3.14/180/180 = T.miniux and [1].ID = T.[1_ID]
1