我无法绞尽脑汁思考如何构造这个 sql 查询。
我有3张桌子。
用户表
tag_ref表
地理位置表
我需要做的是根据位置以及与他们关联的标签来查找用户。我有两个查询单独工作。
这是我用于位置查询的:
$sql_search_people = "SELECT user_id, ( 3959 * acos( cos( radians(?) ) * cos( radians( geolat ) ) * cos( radians( geolon ) - radians(?) ) + sin( radians(?) ) * sin( radians( geolat ) ) ) ) AS distance FROM geolocation
HAVING distance < '25'";
然后我需要根据 tag_ref 表中的 tag_id 过滤结果。用户可以通过多个标签进行搜索。我在这里单独做了这个:
$sql_search_people = "SELECT b.user_id, b.name, b.picture, b.tagline, b.genres FROM tag_ref AS a LEFT JOIN users AS b ON a.user_id = b.user_id WHERE a.tag_id IN ($in) GROUP BY a.user_id";
现在我只需要弄清楚如何将两者组合成一个查询。我无法弄清楚!我尝试过联接和子查询,但我真的很难理解这些。
任何帮助将不胜感激。
** 更新 **
玩了一会儿之后,我设法让它发挥作用:
$sql_search_people = "SELECT a.user_id, b.user_id, c.user_id, c.tag_id, b.name, ( 3959 * acos( cos( radians(?) ) * cos( radians( geolat ) ) * cos( radians( geolon ) - radians(?) ) + sin( radians(?) ) * sin( radians( geolat ) ) ) ) AS distance FROM geolocation AS a RIGHT JOIN tag_ref AS c ON a.user_id = c.user_id RIGHT JOIN users AS b ON a.user_id = b.user_id WHERE c.tag_id IN ($in) HAVING distance < '25' ";
但是,当用户拥有多个标签时,这当然是重复的结果。当我将 group by 添加到 group by user_id 时,查询失败?
我有一个想法,使用第一个查询是临时表来调用第二个查询:
SELECT b.user_id, b.name, b.picture, b.tagline, b.genres FROM tag_ref AS a LEFT JOIN users AS b ON a.user_id = b.user_id, (SELECT user_id, ( 3959 * acos( cos( radians(?) ) * cos( radians( geolat ) ) * cos( radians( geolon ) - radians(?) ) + sin( radians(?) ) * sin( radians( geolat ) ) ) ) AS distance FROM geolocation
HAVING distance < '25') as location WHERE a.tag_id IN ($in) GROUP BY a.user_id
如果其他人也面临同样的情况,我设法解决了这个问题。
我不知道我最初想做什么。比那简单得多。 这是我所做的:
检查每个标签并添加到数组中:
$in = "";
foreach ($tags as $i => $item)
{
if(!is_numeric($item)){
return $response = array(
'status' => 'error',
'message' => 'invalid category',
'code' => 400
);
}
$key = ":id".$i;
$in .= "$key,";
$in_params[$key] = $item; // collecting values into key-value array
}
$in = rtrim($in,",");
查询:
$sql = '
SELECT l.user_id, l.city, u.name, u.tagline, u.photo_id, u.specialties, p.image
FROM location l
LEFT JOIN user_categories AS c ON l.user_id = c.user_id
LEFT JOIN user AS u ON l.user_id = u.id
LEFT JOIN photos AS p ON u.photo_id = p.id
WHERE ST_Distance_Sphere(l.point, POINT(:lon, :lat)) < :distance AND c.tagid IN ('.$in.')
GROUP BY l.user_id
';
$stmt = $conn->prepare($sql);
$params = ['lat' => $lat, 'lon' => $lon, 'distance' => $distance];
$stmt->execute(array_merge($params,$in_params));