【问题标题】:PHP Sub-query to select all user's profile who are friends with me in Friends tablePHP子查询在Friends表中选择所有与我成为朋友的用户个人资料
【发布时间】:2014-09-11 13:33:45
【问题描述】:

在此处发布问题之前,我进行了几个小时的研究,但没有运气。 让我们从表格中的示例开始,以便您轻松理解我要做什么:

在个人资料表中,我注册了个人资料,他们的 profile_id 是:
约翰123
乔伊
史密斯
哈西

以上个人资料是彼此的朋友,朋友表由两个属性组成,即 profile_one 和 profile 2。以下是他们如何成为朋友:

john123 与 joee 的朋友
john123 与史密斯的朋友
john123 与 hassey 的朋友

hassey 和 joee 的朋友
哈西和史密斯的朋友

当我尝试获取当前登录用户的朋友时,它可以正常工作并使用以下查询返回 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 注意:未定义索引:第 610 行的 profile_one
以下是好友表

+-------+-----------+------------+
|   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 与朋友表中的 profile_one 或 profile_two 匹配。

【问题讨论】:

  • james,如果你能阅读MY POST 了解如何提出正确的 mysql 问题,我会这样做,这样我就可以编辑/测试我的答案并确保它解决了你的问题

标签: php mysql


【解决方案1】:

我认为您没有理由使用子查询。如果可以使用子查询完成某些操作,那么您很有可能可以使用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 替换为 0 时才有效,WHERE friendsTbl.profile_one = 1 OR friendsTbl.profile_two = 1 而且 foreach 循环没有获取这些用户的个人资料信息,而是我自己的信息相反,正如我在调试中看到的那样。它确实显示了我的朋友但没有得到他们的信息的用户。如果这确实是我想要的,那就太好了。
  • 我很确定它有效,我在测试数据库上对其进行了测试。稍后我会添加一个 sqlfiddle。
  • 这是 sqlfiddle - sqlfiddle.com/#!2/d0ca8f/2。显然我忘记替换查询中的列,因此它无法正常工作。
  • 我已将其替换为 $this->myID 并且效果很好:) 非常感谢
  • 是否可以同时输出两个用户的名字和姓氏? John123 用户的名字和姓氏?
【解决方案2】:

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

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}')

你基本上是在说 where 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
)

【讨论】:

  • 还有其他方法可以做我想做的事吗?
  • 谢谢约翰,至少我得到了不同的输出,它返回 true,因为我看到使用 vardumb($query)。我收到错误,未定义的索引:friend_one 和friend_two。此外,它现在说我有 1 个朋友而不是 2 个,所以我调试了 while 循环,while 循环只选择第一行的一个字段并跳过其余字段。 while 循环是 while ($row = $query->fetch_array()) { $result[] = $row; }
  • @JamesSmith 你能自己执行查询吗...不是在 php 中,而是在 phpmyadmin 或 mysql 工作台中?
  • 我试过了,如果我用 $this->myID 替换它,它只会显示 john123,因为这是 user_session。它不会显示与 john123 成为朋友的用户,他们是 joee、smith 和 hassey。
  • @JamesSmith 听起来你需要调试 php 代码.. 查询返回你想要的:)
【解决方案3】:

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

SELECT friends_with
FROM FriendsTbl
WHERE profile = {your_profile_id}

【讨论】:

  • 谢谢亚历克斯,但有一个问题。例如,如果我添加一个朋友,我的用户 ID 将存储在属性列中,而该朋友的用户 ID 将存储在 profile_two 属性中,但是如果他们添加我,那么会发生相反的情况,我是 PHP 的中间人,而不是真的知道如何强制将我的 ID 存储在个人资料属性中,并将好友 ID 存储到 Friends_with 属性中。我可以谷歌查找任何关键字建议吗?或您可以提供给我的任何链接?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-21
  • 1970-01-01
  • 2014-06-21
  • 1970-01-01
  • 2014-03-27
  • 1970-01-01
相关资源
最近更新 更多