Php 向MySQL查询添加联接会引发奇怪的错误
我正在创建一个MySQL过程。表及其数据由MAXMIND的位置IP服务提供,可以找到。该过程不是由我创建的,但它完全满足我的需要,只是我正在尝试向查询添加联接。我正在尝试获取“目的地”的id并查询照片表以获取照片 表格Php 向MySQL查询添加联接会引发奇怪的错误,php,mysql,performance,stored-procedures,join,Php,Mysql,Performance,Stored Procedures,Join,我正在创建一个MySQL过程。表及其数据由MAXMIND的位置IP服务提供,可以找到。该过程不是由我创建的,但它完全满足我的需要,只是我正在尝试向查询添加联接。我正在尝试获取“目的地”的id并查询照片表以获取照片 表格 | locations || photos | |________________||________________| | | | | | id | | id
| locations || photos |
|________________||________________|
| | | |
| id | | id |
| latitude | | lid |
| longitude | | pid |
代码:
CREATE PROCEDURE `GEODIST`( IN userid int, IN dist int, IN olat float, IN olon float ) DETERMINISTIC READS SQL DATA
BEGIN
DECLARE mylon DOUBLE;
DECLARE mylat DOUBLE;
DECLARE lon1 FLOAT;
DECLARE lon2 FLOAT;
DECLARE lat1 FLOAT;
DECLARE lat2 FLOAT;
SET mylon = olon;
SET mylat = olat;
SET lon1 = mylon - dist / abs( cos( radians( mylat ) ) * 69 );
SET lon2 = mylon + dist / abs( cos( radians( mylat ) ) * 69 );
SET lat1 = mylat - ( dist / 69 );
SET lat2 = mylat + ( dist / 69 );
SELECT destination.id, destination.latitude, destination.longitude, photos.lid,
photos.pid, 3956 * 2 * ASIN(SQRT( POWER(SIN((origin.latitude -destination.latitude) * pi()/180 / 2), 2) +COS(origin.latitude * pi()/180) * COS(destination.latitude * pi()/180) *POWER(SIN((origin.longitude -destination.longitude) * pi()/180 / 2), 2) )) AS distance
FROM locations destination, locations origin JOIN photos ON photos.lid = destination.id WHERE origin.id = userid
AND destination.longitude BETWEEN lon1 AND lon2 AND destination.latitude BETWEEN lat1 and lat2
HAVING distance < dist ORDER BY distance LIMIT 50;
END
如果查询中没有JOIN子句,一切正常。查询正常工作,因此我知道它与连接有关,但我不知道发生了什么。非常感谢您提供的任何帮助。您不应将逗号运算符和显式联接混用在一起,因为:
...
FROM locations destination, locations origin JOIN photos ON photos.lid = destination.id
...
您应该改用交叉连接:
FROM locations destination CROSS JOIN locations origin JOIN photos ON photos.lid = destination.id
手册章节对此进行了说明:
内部连接和(逗号)在没有
连接条件:两者都在
指定的表(即,第一个表中的每一行都是
已联接到第二个表中的每一行)
但是,逗号运算符的优先级小于内部运算符的优先级
连接、交叉连接、左连接等。如果将逗号连接与
其他联接类型当存在联接条件时,会出现
可能出现“on子句”中的表单未知列“col_name”
不应将逗号运算符和显式联接混合使用,因为:
...
FROM locations destination, locations origin JOIN photos ON photos.lid = destination.id
...
您应该改用交叉连接:
FROM locations destination CROSS JOIN locations origin JOIN photos ON photos.lid = destination.id
手册章节对此进行了说明:
内部连接和(逗号)在没有
连接条件:两者都在
指定的表(即,第一个表中的每一行都是
已联接到第二个表中的每一行)
但是,逗号运算符的优先级小于内部运算符的优先级
连接、交叉连接、左连接等。如果将逗号连接与
其他联接类型当存在联接条件时,会出现
可能出现“on子句”中的表单未知列“col_name”
这是您的
from
条款:
FROM locations destination,
locations origin JOIN
photos
ON photos.lid = destination.id
WHERE origin.id = userid AND
destination.longitude BETWEEN lon1 AND lon2 AND
destination.latitude BETWEEN lat1 and lat2
您正在混合隐式联接和显式联接。这是个坏主意,现在你至少知道了一个原因。你会犯奇怪的错误。一条简单的规则:在from
子句中不要使用逗号
您可以通过将,
替换为交叉连接来解决此问题:
FROM locations destination CROSS JOIN
locations origin JOIN
photos
ON photos.lid = destination.id
WHERE origin.id = userid AND
destination.longitude BETWEEN lon1 AND lon2 AND
destination.latitude BETWEEN lat1 and lat2
交叉连接
几乎与逗号完全相同。除此之外,from
子句的其余部分都知道第一个表中的列。但是,您应该真正修复连接
s。这是一个猜测:
FROM photos JOIN
locations destination
ON photos.lid = destination.id JOIN
locations origin
ON origin.id = userid
WHERE destination.longitude BETWEEN lon1 AND lon2 AND
destination.latitude BETWEEN lat1 and lat2
这是您的from
条款:
FROM locations destination,
locations origin JOIN
photos
ON photos.lid = destination.id
WHERE origin.id = userid AND
destination.longitude BETWEEN lon1 AND lon2 AND
destination.latitude BETWEEN lat1 and lat2
您正在混合隐式联接和显式联接。这是个坏主意,现在你至少知道了一个原因。你会犯奇怪的错误。一条简单的规则:在from
子句中不要使用逗号
您可以通过将,
替换为交叉连接来解决此问题:
FROM locations destination CROSS JOIN
locations origin JOIN
photos
ON photos.lid = destination.id
WHERE origin.id = userid AND
destination.longitude BETWEEN lon1 AND lon2 AND
destination.latitude BETWEEN lat1 and lat2
交叉连接
几乎与逗号完全相同。除此之外,from
子句的其余部分都知道第一个表中的列。但是,您应该真正修复连接
s。这是一个猜测:
FROM photos JOIN
locations destination
ON photos.lid = destination.id JOIN
locations origin
ON origin.id = userid
WHERE destination.longitude BETWEEN lon1 AND lon2 AND
destination.latitude BETWEEN lat1 and lat2
重做我的评论-地点目的地和地点来源之间的关系是什么?交叉连接?这是一种故意的交叉连接(交叉自连接),因此您可以获得起点和终点的所有组合,以获得所有位置之间的距离。。。然后过滤掉那些想要的组合。@VMai这正是我所怀疑的…因为他在那里混合了连接语法。嘿,你在回答问题时没有确认,只是回答:)要么放弃join操作符的老式逗号语法,使用join
关键字,-要么-将join谓词移动到WHERE
子句。不要混合使用老式的逗号语法和JOIN。。在
syntax上。重做我的注释-位置目标和位置原点之间的关系是什么?交叉连接?这是一种故意的交叉连接(交叉自连接),因此您可以获得起点和终点的所有组合,以获得所有位置之间的距离。。。然后过滤掉那些想要的组合。@VMai这正是我所怀疑的…因为他在那里混合了连接语法。嘿,你在回答问题时没有确认,只是回答:)要么放弃join操作符的老式逗号语法,使用join
关键字,-要么-将join谓词移动到WHERE
子句。不要混合使用老式的逗号语法和JOIN。。关于
语法。这是很好的信息。我将尝试一下,我对MySQL不是很精通,而且还在学习。这对我来说是全新的。谢谢你的帮助。我要试试这个,然后回来汇报。谢谢谢谢,谢谢你的帮助。我希望抓取所有目的地,然后抓取与这些目的地相关的所有照片,也许我在这里做错了什么,但这次查询实际上运行了,这是向前迈出的一大步,但它只提供了有照片的目的地,它没有为我提供任何目的地,照片表中没有任何列表。我真的很感谢你的帮助。我试着完全按照第一段代码中的建议使用交叉连接。我只是试着将代码更改为您提供的代码的botom部分,似乎得到了相同的结果。它提供的结果和复制的次数与照片相同:例如,如果location1有5张照片,则结果中有5张location1,但如果location2没有照片,则location2根本不在结果列表中。@mcbeav。原始查询中的逻辑根本不正确。然而,你的问题是语法问题,而不是逻辑问题。我建议你问另一个问题,包括样本数据和期望的结果。这很好