PHP子查询选择朋友表中与我成为朋友的所有用户的个人资料

时间:2014-09-11 13:33:46

标签: php mysql

我在这里发表一个问题并没有运气之前做了几个小时的研究。 让我们从表格中的示例开始,这样您就可以很容易地理解我想要做的事情:

在个人资料表格中,我注册了个人资料,其profile_id为:
john123
joee
史密斯
hassey

上述个人资料是彼此的朋友,而朋友表包含两个属性,即profile_one和个人资料二。以下是他们如何成为彼此的朋友:

john123与joee的朋友 john123与史密斯的朋友 john123与hassey的朋友
哈希的朋友和乔伊 哈希的朋友和史密斯一起

当我尝试获取当前登录用户的朋友时,它运行正常并使用以下查询返回true:

$query = $this->db->query("SELECT profile_one, profile_two 
                           FROM friendsTbl
                           WHERE profile_one = '{$this->myID}' OR profile_two = '{$this->myID}'")

现在我想获取这些用户配置文件信息,以便我可以显示它们的名字和姓氏,因此我使用了如下的子查询,但是它返回false并且我得到了致命错误的错误:调用到非对象的成员函数fetch_array()。该错误显示在我使用while循环的行上。子查询:

$query = $this->db->query("SELECT profile_id FROM profileTbl
                           WHERE profile_id IN (SELECT profile_one, profile_two 
                           FROM friendsTbl
                           WHERE profile_one = '{$this->myID}' OR profile_two = '{$this->myID}')");

如上所述,上述内容会返回错误和致命错误。 我真的很感谢你对此的帮助,因为我一直试图这样做一天没有任何运气。

注意:我正在为这个项目使用类和函数,因此它是面向对象的。


@John,在您修改查询之后。以下是输出内容: 注意:未定义的索引:第609行上的profile_one< - 此行中的代码是foreach内的$ profile_one = $ profiles ['profile_one']($ profile为$ profiles)
注意:未定义的索引:第610行的profile_one< - 此行上的代码是foreach内的$ profile_one = $ profiles ['profile_two']($ profile为$ profiles)

以下是朋友表

+-------+-----------+------------+
|   id  |profile_one| profile_two|
+-------+-----------+------------+
|   33  | john123   |  hassey    |
|   34  | john123   |  smith     |
|   35  | joee      |  john123   |
+-------+-----------+------------+

以下是个人资料表:

+-------+-----------+-----------+-------------------+
| u_id  |   f_name  |   l_name  |     profile_id    |
+-------+-----------+-----------+-------------------+
|  23   |   john    |    larr   |   john123         |
|  26   |   joee    |    attwo  |   joee            |
|  27   |   smith   |    Mark   |   smith           |
|  28   |   hassey  |    Mess   |   hassey          |
+-------+-----------+-----------+-------------------+

现在我期望结果是无论用户登录哪个是通过传递包含用户会话ID的$ this-> myid,它都会向那些他们是朋友的用户显示这些朋友。这在我最初发布的原始sql语句中有效,但是现在我也希望朋友f_name和l_name显示哪些匹配profile表中的profile_id与friends_one中的profile_one或profile_two匹配。

3 个答案:

答案 0 :(得分:2)

我没有看到您使用子查询的原因。如果可以使用子查询完成某些操作,那么您很有可能使用JOIN执行此操作。如果可行,使用JOIN是更好的解决方案,通常更快。

尝试使用类似的查询:

SELECT 
    friendsTbl.*,
    profileTbl.*
FROM friendsTbl
LEFT JOIN profileTbl ON (profile_name = IF(friendsTbl.profile_one = 'john123',friendsTbl.profile_two, friendsTbl.profile_one) )
WHERE friendsTbl.profile_one = 'john123' OR friendsTbl.profile_two = 'john123'

以下是sqlfiddle,其中显示了用户john123

的所有朋友

答案 1 :(得分:1)

您不能在子查询中选择两件事

SELECT profile_id FROM profileTbl
WHERE profile_id IN (SELECT profile_one, profile_two # issue here
FROM friendsTbl
WHERE profile_one = '{$this->myID}' OR profile_two = '{$this->myID}')

你基本上说id = 1,2,其中1和2是列

您可以尝试CASE声明

SELECT profile_id 
FROM profileTbl
WHERE profile_id IN 
(   SELECT 
        CASE WHEN profile_one = '{$this->myID}' THEN profile_one
             WHEN profile_two = '{$this->myID}' THEN profile_two 
        END
FROM friendsTbl
)

答案 2 :(得分:1)

我认为问题是你的架构。在n-n关系表中,您要存储友谊(friendsTbl),您应该在两列上强制执行UNIQUE复合索引,并使每个列特定于关系的一部分。这样,您可以将第一列profile_one(并将其重命名)视为profile,将第二列视为friends_with。那么,那就得到你是谁的朋友:

SELECT friends_with
FROM FriendsTbl
WHERE profile = {your_profile_id}