如何创建一个JOIN查询,为每个用户找到最近的商店

时间:2019-07-10 13:30:26

标签: sql ms-access

我有两个简单的表:

void menu()
{

    int sub1;

    printf("click\n");
    glutCreateMenu(GoMenu);
    glutAddMenuEntry("Define source", 1);
    glutAddMenuEntry("Define sink", 2);
    glutAddMenuEntry("Recharge device", 3);
    glutAttachMenu(GLUT_LEFT_BUTTON);
}

我想要一个查询,该查询可以让所有拥有最近商店的用户获得查询。我不在乎地球的圆度,因为每个用户都将在附近拥有一家商店。这就是为什么我选择使用毕达哥拉斯来寻找最近的距离的原因:

User:
id - int
name - string
lat - decimal
long - decimal

Store:
id - int
name - string
lat - decimal
long - decimal

不幸的是,这给了我笛卡尔积,这样我就可以使所有用户与每家商店保持距离。有没有办法只获得最近的商店?

谢谢

2 个答案:

答案 0 :(得分:1)

您可以按用户分组并计算最小值(距离),然后链接回第一个查询,以找出与用户之间的距离是哪个商店。

这是您的查询,为清楚起见删除了某些字段(并为User.Id加上别名)

SELECT 
    User.id as userid, 
    Sqr((User.Lat - Store.Lat)^2+(User.Long - Store.Long)^2) AS distance
FROM User, Store

这包装了第一个查询,以计算每个用户到商店的最小距离

select userid, min(distance) from (
    SELECT 
        User.id as userid, 
        Sqr((User.Lat - Store.Lat)^2+(User.Long - Store.Long)^2) AS distance
    FROM User, Store
 ) as x 
group by userid

将其加入您的原始查询以填充用户字段,并找出距用户(最小)距离的商店


select z.*
from (
    select userid, min(distance) as distance from (
        SELECT 
            User.id as userid, 
            Sqr((User.Lat - Store.Lat)^2+(User.Long - Store.Long)^2) AS distance
        FROM User, Store
     ) as x 
group by userid
) as y inner join
(
    SELECT 
        User.Id as UserId, ... (populate the remaining user fields), 
        Store.*, 
        Sqr((User.Lat - Store.Lat)^2+(User.Long - Store.Long)^2) AS distance
    FROM User, Store
) as z
on y.userid = z.userid and y.distance = z.distance

答案 1 :(得分:0)

您需要做的是交叉连接表和WHERE子句,在其中选择距离每个用户最小距离的商店,如下所示:

select u.*, s.*
from user as u, store as s
where ((u.Lat - s.Lat)^2+(u.Long - s.Long)^2) = (
  select min((u.Lat - ss.Lat)^2+(u.Long - ss.Long)^2)
  from  store as ss
)

您无需将Sqr()应用于计算。