我有两个简单的表:
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
不幸的是,这给了我笛卡尔积,这样我就可以使所有用户与每家商店保持距离。有没有办法只获得最近的商店?
谢谢
答案 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()
应用于计算。