【问题标题】:inner join mysql php内连接mysql php
【发布时间】:2018-10-24 21:04:37
【问题描述】:

如何根据用户表中的用户 ID 选择用户名、头像等而不会出现致命错误:请未捕获 PDOException?

PHP:

$req_pm_list = $sql_connection->prepare('SELECT pm.receiver, pm.date_sent, pm.unread, users.username, users.avatar, users.session_id
    FROM pm
    INNER JOIN users AS user_receiver ON pm.receiver = users.id
    INNER JOIN users AS user_sender ON pm.sender = users.id
    WHERE sender = :id OR receiver = :id 
    GROUP BY users.id 
    ORDER BY date_sent ASC');
$req_pm_list->bindValue(':id', $_SESSION['id']);
$req_pm_list->execute();
$pm_list = $req_pm_list->fetchAll(PDO::FETCH_ASSOC);

【问题讨论】:

  • 您使用的是哪个 RDBMS,mysql 还是 mssql?这里有两种不同的动物。
  • 您不应该在选择列表、加入条件和分组依据中使用别名 no 而不是 users
  • 请向我们提供您收到的错误。 php.net/manual/en/pdo.errorinfo.php另外是仿真吗?没有它就不能使用相同的占位符名称。
  • 是 users 还是 n.你决定
  • 以后,请在问题中包含完整的错误文本。

标签: php sql session pdo


【解决方案1】:

问题在于,因为您在两个连接中都为 users 表加上了别名,所以在 JOIN 条件、GROUP BYSELECT 列表中对 users 的引用不明确或无效。

您想从SELECT 中选择哪个用户名和头像,发送者还是接收者? 因为您已经JOINed 两次,使用不同的别名,所以您需要明确您正在使用users 表的哪个副本

它必须是 user_receiver.usernameuser_receiver.avataruser_sender.usernameuser_sender.avatar,或全部。对 users 的引用此时无效,因为没有加入未别名的 users 表。

同样,users 的别名应该用在JOIN 条件中

我不确定你为什么还要做GROUP BY,但同样的事情发生在那里,users 引用无效,因为连接中没有未别名的users 表,你必须告诉它使用哪个用户表的副本。

查询应该看起来更像这样(我省略了GROUP BY,因为在没有看到一些实际表数据的情况下,不清楚你想用它来完成什么。

SELECT pm.receiver, pm.date_sent, pm.unread, 
    user_receiver.username AS receiver_name, 
    user_receiver.avatar AS receiver_avatar,
    user_receiver.session_id AS receiver_session_id,
    user_sender.username AS sender_name, 
    user_sender.avatar AS sender_avatar,
    user_sender.session_id AS sender_session_id
FROM pm
INNER JOIN users AS user_receiver ON pm.receiver = user_receiver.id
INNER JOIN users AS user_sender ON pm.sender = user_sender.id
WHERE sender = :id OR receiver = :id 
ORDER BY date_sent ASC 

【讨论】:

  • users.session_id 需要为每个别名复制。
  • 您应该为所有重复的列名提供别名,例如user_receiver.username AS receiver_username
  • 两者都对,我不确定是否要处理 session_id,因为我怀疑它可能与 group by 纠缠在一起
【解决方案2】:

当您为表指定别名时,您不能再引用原始表名,您必须使用别名。所以users.columnName 是错误的,你必须在所有这些地方酌情使用user_receiver.columnNameuser_sender.columnName

如果您总是想从表中选择与:id 对应的列,可以使用IF 函数。如果您想为其他用户选择列,只需在那些IF 函数中将sender = :id 更改为receiver = :id

也不需要GROUP BY,你没有聚合任何东西。

SELECT pm.receiver, pm.date_sent, pm.unread, 
    IF(sender = :id, user_sender.username, user_receiver.username) AS username, 
    IF(sender = :id, user_sender.avatar, user_receiver.avatar) AS avatar,
    IF(sender = :id, user_sender.session_id, user_receiver.session_id) AS session_id
FROM pm
INNER JOIN users AS user_receiver ON pm.receiver = user_receiver.id
INNER JOIN users AS user_sender ON pm.sender = user_sender.id
WHERE sender = :id OR receiver = :id 
ORDER BY date_sent ASC

【讨论】:

  • 您好,谢谢!刚刚错过FROM pm,请求现在有效。但它仍然没有给我发送 PM 的用户列表。我认为我们需要GROUP BY,但是如何将它与别名一起使用?
  • 你为什么需要GROUP BY?这只会将多行合并为一行,不会返回其他信息。
  • 我的查询显示:id中用户的用户名和头像。我在第二段中解释了如何获取其他用户的用户名和头像。您也可以只使用user_sender.username 始终获取发件人,无论它们是否与:id 相同。
  • @Joe278 查看另一个答案,他返回发送者和接收者的姓名和头像。
  • 因为我在 foreach 循环中使用数据
猜你喜欢
  • 2011-09-08
  • 1970-01-01
  • 1970-01-01
  • 2020-12-11
  • 2012-11-10
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
相关资源
最近更新 更多