我如何使用同一个表查询共同的朋友?

时间:2016-04-30 11:50:41

标签: php mysql

我有表朋友和表格用户

朋友表格中的所有ID(user_one,user_two)均为表格用户

中的有效用户

Lets说当前的LoggIn用户访问了另一个用户的个人资料,他访问过的个人资料ID是27

请注意:我正在使用$ _GET全局变量来获取此个人资料ID。 e.g

$user_id = $_GET['id'];

然后他点击链接查看该用户的朋友(27)

现在,他的朋友们是:18岁和33岁。

如果当前(18)用户也是用户33的朋友,请问如何查询数据库?

注意:用户18是当前的LoggIn用户

下面是明确的朋友表格结构:

u1 | u2

18 | 33

33 | 27

27 | 18

下面是我试过的代码:

SELECT IF(user_one = '$IsLoggIn' OR user_two = '".$_GET['id']."', user_two, user_one)
FROM friends
WHERE ((user_one = '$IsLoggIn' OR user_two = '".$_GET['id']."') OR (user_two ='$IsLoggIn' OR user_two = '".$_GET['id']."')

请不要使用sql。谢谢

2 个答案:

答案 0 :(得分:0)

我确信这不是最快的解决方案(根本不是......)但至少可以起作用。

我已经用语句实现了它,以避免Niet在评论中提到的SQL注入。

PHP代码:

<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// prepare and bind
$stmt = $conn->prepare("
select
    user_two as friend_id,
    if(exists(
        select *
        from friends
        where (user_one = friend_id and user_two = ?)
            or (user_two = friend_id and user_one = ?)),
        'yes', 'no') as mutual
from friends
where user_one = ? and user_two <> ?
union
select
    user_one as friend_id,
    if(exists(
        select *
        from friends
        where
            (user_one = friend_id and user_two = ?)
            or
            (user_two = friend_id and user_one = ?)),
        'yes', 'no') as mutual
from friends
where user_two = ? and user_one <> ?
");
$stmt->bind_param("iiiiiiii", $myUserId, $myUserId, $visitedUserId, $myUserId, $myUserId, $myUserId, $visitedUserId, $myUserId);

// set parameters and execute
$myUserId = $IsLoggIn;
$visitedUserId = $_GET['id'];
$stmt->execute();

// bind variables to prepared statement
$stmt->bind_result($visitedUserFriendsId, $isMutual);

// fetch values (here you can do whatever you want with results)
while ($stmt->fetch()) {
    printf("%s %s\n", $visitedUserFriendsId, $isMutual);
}

$stmt->close();
$conn->close();
?>

如果您在表格中有这种关系朋友(27岁是25岁的朋友,但18位不是):

user_one | user_two
      18 |       33
      33 |       27
      27 |       18
      27 |       25

当用户18访问用户27个人资料时,该SQL查询将返回:

friend_id | mutual
       25 |     no
       33 |    yes

然后你可以很容易地用PHP中的结果工作。

答案 1 :(得分:0)

我知道你已经有了答案。我将使用与@nanocv相同的PHP代码,以使其简短易懂。

您可以尝试此查询(此查询将返回所有访问过的用户个人资料的朋友,将第二列视为相互:是或否):

$stmt = $conn->prepare("
SELECT IF(f.user_one = ?,f.user_two,f.user_one) AS friend_id,     
IF((
    SELECT count(*) 
    FROM friends mf WHERE 
    (mf.user_one = friend_id AND mf.user_two = ?) OR 
    (mf.user_two = friend_id AND mf.user_one = ?) OR 
    (friend_id = ?) /* this return who is visiting as mutual! */

) > 0,'yes','no') AS mutual
FROM friends f 
WHERE (f.user_one = ? OR f.user_two = ?)
/* the next line will not return who is visiting as friend, 
   remove it if you want it to be return as friend */
AND (f.user_one != ? AND f.user_two != ?)
");

$stmt->bind_param('iiiiiiii', $visitedUserId, $myUserId, $myUserId,$myUserId, $visitedUserId, $visitedUserId, $myUserId, $myUserId);

如果friends表中的数据重复如下:

| u1 | u2 |
|----|----|
|  2 | 1  |
|  1 | 2  |

您需要在查询结尾添加GROUP BY friend_id

此查询将仅返回所访问的用户个人资料的朋友和登录的共同的用户:

$stmt = $conn->prepare("SELECT IF(f.user_one = ?,f.user_two,f.user_one) AS friend_id
    FROM friends f 
    WHERE (f.user_one = ? OR f.user_two = ?) AND 
    IF((
        SELECT count(*) 
        FROM friends mf WHERE 
        (mf.user_one = IF(f.user_one = ?,f.user_two,f.user_one) AND mf.user_two = ?) OR 
        (mf.user_two = IF(f.user_one = ?,f.user_two,f.user_one) AND mf.user_one = ?)

    ) > 0,TRUE,FALSE);");

    $stmt->bind_param('iiiiiii', $visitedUserId,$visitedUserId,$visitedUserId,$visitedUserId, $myUserId,$visitedUserId, $myUserId);