从多个表中选择过滤器
Posted
技术标签:
【中文标题】从多个表中选择过滤器【英文标题】:Select Filter From Multiple Tables 【发布时间】:2019-08-12 13:52:07 【问题描述】:我有一个用户聊天系统,它有 2 个表:用户表和关注者表。我正在执行搜索,我想获得我关注的用户
users
表将此作为主键:user_id
,followers
表具有以下列following_id follower_id is_typing active
我如何加入这两个表以获得我的结果?
我一直在这样做:
function Wo_GetNearbyFriends($args = array())
global $wo, $sqlConnect;
if ($wo['loggedin'] == false || empty($args))
return false;
$options = array(
"offset" => false,
"gender" => false,
"name" => false,
"distance" => false,
"relship" => false,
"status" => false,
"fid_5" => false,
"fid_6" => false,
"fid_7" => false,
"fid_8" => false,
"limit" => 20
);
$args = array_merge($options, $args);
$offset = Wo_Secure($args['offset']);
$gender = Wo_Secure($args['gender']);
$name = Wo_Secure($args['name']);
$loc_distance = Wo_Secure($args['distance']);
$status = Wo_Secure($args['status']);
$relship = Wo_Secure($args['relship']);
$fid_5 = Wo_Secure($args['fid_5']);
$fid_6 = Wo_Secure($args['fid_6']);
$fid_7 = Wo_Secure($args['fid_7']);
$fid_8 = Wo_Secure($args['fid_8']);
$limit = Wo_Secure($args['limit']);
$unit = 6371;
$user_lat = $wo['user']['lat'];
$user_lng = $wo['user']['lng'];
$user = $wo['user']['id'];
$t_users = T_USERS;
$t_followers = T_FOLLOWERS;
$distance = 25;
$data = array();
$sub_sql = "";
if ($loc_distance && is_numeric($loc_distance) && $loc_distance > 0)
$distance = $loc_distance;
if ($name)
$name = Wo_Secure($name);
$sub_sql .= " AND (`username` LIKE '%$name%' OR `first_name` LIKE '%$name%' OR `last_name` LIKE '%$name%') ";
if (isset($status) && $status != false)
if ($status == 1)
$time = time() - 60;
$sub_sql .= " AND `lastseen` > '$time'";
else if ($status == 0)
$time = time() - 60;
$sub_sql .= " AND `lastseen` < '$time'";
if ($relship && in_array($relship, array_keys($wo['relationship'])))
$sub_sql .= " AND `relationship_id` = '$relship' ";
if ($offset && is_numeric($offset) && $offset > 0)
$sub_sql .= " AND `user_id` < '$offset' AND `user_id` <> '$offset' ";
if ($gender && in_array($gender, array_keys($wo['genders'])))
$sub_sql .= " AND `gender` = '$gender' ";
if($fid_5 && is_numeric($fid_5) && $fid_5 > 0)
$sub_sql .= " AND `fid_5` = '$fid_5' ";
if($fid_6 && is_numeric($fid_6) && $fid_6 > 0)
$sub_sql .= " AND `fid_6` = '$fid_6' ";
if($fid_7 && is_numeric($fid_7) && $fid_7 > 0)
$sub_sql .= " AND `fid_7` = '$fid_7' ";
if($fid_8 && is_numeric($fid_8) && $fid_8 > 0)
$sub_sql .= " AND `fid_8` = '$fid_8' ";
$sql = "SELECT `user_id`, ( $unit * acos(cos(radians('$user_lat')) * cos(radians(lat)) * cos(radians(lng) - radians('$user_lng')) + sin(radians('$user_lat')) * sin(radians(lat))) ) AS distance FROM $t_users WHERE `user_id` <> '$user' $sub_sql AND `user_id` IN (SELECT `follower_id` FROM $t_followers WHERE `follower_id` <> $user AND `following_id` = $user AND `active` = '1') AND `user_id` IN (SELECT `following_id` FROM $t_followers WHERE `follower_id` = $user AND `following_id` <> $user AND `active` = '1') AND `lat` <> 0 AND `lng` <> 0 HAVING distance < '$distance' ORDER BY `user_id` DESC LIMIT 0, $limit ";
$query = mysqli_query($sqlConnect, $sql);
while ($fetched_data = mysqli_fetch_assoc($query))
$fetched_data['user_data'] = Wo_UserData($fetched_data['user_id']);
$fetched_data['user_data']['age'] = Wo_GetUserCountryName($fetched_data['user_data']);
$fetched_data['user_geoinfo'] = $fetched_data['user_data']['lat'] . ',' . $fetched_data['user_data']['lng'];
if ($fetched_data['user_data']['share_my_location'] == 1)
$data[] = $fetched_data;
return $data;
【问题讨论】:
您能否澄清您的问题,尤其是您解释查询应该做什么的部分?另外,我是否正确假设following_id
和follower_id
都包含用户ID,并引用user_id
?
@KIKOSoftware user_id
带有用户 ID,follower_id
和 following_id
带有来自用户表的用户 ID 的引用。我试图在计算他们的距离时获得用户的关注者
@GordonLinoff 请问我如何获得问题的样本数据?
您应该在问题中解释基本内容,而不是在评论中。您仍然可以对其进行编辑。我也想知道$sub_sql
包含什么。您的查询中有很多未定义的变量。
天哪,是的,你有。但这不是应该这样做的。首先,您在外部发布代码,这并不好,其次您的问题应该是minimal and repeproducible。这两者都不是。您也没有提供示例数据或完整的表模式。如您所见,提问很困难。不过,我现在会尝试回答....让我看看....这可能需要一段时间。
【参考方案1】:
这里只是加入。拥有两个用户行后,您可以对他们的数据应用距离计算。
select *
from t_users u1
join t_users u2
on u1.user_id < u2.user_id
and (u1.user_id, u2.user_id) in (select follower_id, following_id from t_followers)
and (u1.user_id, u2.user_id) in (select following_id, follower_id from t_followers);
演示:https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=f29e1d27055575385d4b28d777fd335c
【讨论】:
我喜欢你的方法,很酷。我浏览了演示,我看到用户 1 正在关注 2 个人,用户 2 和 3。请我需要一个 sql 代码来检索他拥有的两个关注者。 @Inspired Prynce Kaka:这与您最初提出的问题不同。如果您不希望那些既被关注又关注自己的用户(在演示中:用户 1 关注用户 2,而用户 2 自己关注用户 1,所以这是我们选择的那对),那么只需删除不想要的子句(这是其中之一我查询中的两个and ...
)。以上是关于从多个表中选择过滤器的主要内容,如果未能解决你的问题,请参考以下文章