我正在尝试显示与用户数据相关的广告 这里的数据是纬度和经度。
ADS
表:广告,包含广告名称,广告文字,经度和纬度
包含用户数据的表格:
TABLE1
:用户ID + 纬度和经度,
TABLE2
:用户ID + 纬度和经度,
TABLE3
:用户ID + 纬度和经度,
TABLE4
:用户ID + 经度和纬度
目的是在广告的纬度和经度与10个范围内的4个表格中一个或多个行的纬度和经度相匹配时显示广告,并限制为3个结果
将一个广告与10公里范围内的一张广告相关联时,它会正常工作,但不会有更多的广告素材
- 我对OUTER JOINS
-
我的查询看起来像这样,我很确定我错了......
SELECT ADS.name, ADS.text,
( 6371 * acos( cos( radians(TABLE1.latitude) )
* cos( radians( ADS.latitude ) )
* cos( radians( ADS.longitude )
- radians(TABLE1.longitude) )
+ sin( radians(TABLE1.latitude) )
* sin( radians( ADS.latitude ) ) ) )
AS check1,
( 6371 * acos( cos( radians(TABLE2.latitude) )
* cos( radians( ADS.latitude ) )
* cos( radians( ADS.longitude )
- radians(TABLE2.longitude) )
+ sin( radians(TABLE2.latitude) )
* sin( radians( ADS.latitude ) ) ) )
AS check2,
( 6371 * acos( cos( radians(TABLE3.latitude) )
* cos( radians( ADS.latitude ) )
* cos( radians( ADS.longitude )
- radians(TABLE3.longitude) )
+ sin( radians(TABLE3.latitude) )
* sin( radians( ADS.latitude ) ) ) )
AS check3,
( 6371 * acos( cos( radians(TABLE4.latitude) )
* cos( radians( ADS.latitude ) )
* cos( radians( ADS.longitude )
- radians(TABLE4.longitude) )
+ sin( radians(TABLE4.latitude) )
* sin( radians( ADS.latitude ) ) ) )
AS check4
FROM ADS
RIGHT OUTER JOIN TABLE1
ON TABLE1.user = ?
RIGHT OUTER JOIN TABLE2
ON TABLE2.user = ?
RIGHT OUTER JOIN TABLE3
ON TABLE3.user = ?
RIGHT OUTER JOIN TABLE4
ON TABLE4.user = ?
HAVING check1 < 10 OR check2 < 10 OR check3 < 10 OR check4 < 10
LIMIT 0,3
答案 0 :(得分:2)
如果user
(或任何TABLEn)中的TABLE1
不唯一,则可能会从ADS
返回同一行的多个副本。
使用查询的方式,如果在TABLE4中找不到指定的用户,则查询将不返回任何行。我怀疑你的意思是LEFT JOIN
,ADS
作为驾驶表,但这只是猜测。我们不知道这些表包含什么,为什么有四个表等等。)
如果您使用RIGHT JOIN的原因,以及带有一个表的查询是否适合您...
如果指定用户的TABLE1,TABLE2,TABLE3,TABLE4中的每一行都有少量行...
您可以将这些表的查询结果连接到单个派生表中,然后连接到派生表。举个例子:
SELECT ADS.name, ADS.text,
( 6371 * acos( cos( radians(t.latitude) )
* cos( radians( ADS.latitude ) )
* cos( radians( ADS.longitude )
- radians(t.longitude) )
+ sin( radians(t.latitude) )
* sin( radians( ADS.latitude ) ) )
) AS check1
FROM ADS
RIGHT
JOIN ( SELECT TABLE1.latitude, TABLE1.longitude
FROM TABLE1 WHERE TABLE1.user = ?
UNION ALL
SELECT TABLE2.latitude, TABLE2.longitude
FROM TABLE2 WHERE TABLE2.user = ?
UNION ALL
SELECT TABLE3.latitude, TABLE3.longitude
FROM TABLE3 WHERE TABLE3.user = ?
UNION ALL
SELECT TABLE4.latitude, TABLE4.longitude
FROM TABLE4 WHERE TABLE4.user = ?
) t
HAVING check1 < 10
LIMIT 3
答案 1 :(得分:0)
这最终是我所需要的:
$reponse = $bdd->prepare('
SELECT * FROM
(
SELECT ADS.id AS id, ADS.name, ADS.text,
( 6371 * acos( cos( radians(t.latitude) )
* cos( radians(ADS.latitude ) )
* cos( radians( ADS.longitude )
- radians(t.longitude) )
+ sin( radians(t.latitude) )
* sin( radians( ADS.latitude ) ) ) )
AS distance
FROM ADS
RIGHT
JOIN ( SELECT TABLE1.latitude, TABLE1.longitude
FROM TABLE1 WHERE TABLE1.user = :user
UNION ALL
SELECT TABLE2.latitude, TABLE2.longitude
FROM TABLE2 WHERE TABLE2.user = :user
UNION ALL
SELECT TABLE3.latitude, TABLE3.longitude
FROM TABLE3 WHERE TABLE3.user = :user
UNION ALL
SELECT TABLE4.latitude, TABLE4.longitude
FROM TABLE4 WHERE TABLE4.user = :user
) t
ON 1
HAVING distance < 10
) req GROUP BY id LIMIT 0,3
');
$reponse->execute(array('user' => $_SESSION['id']));