【问题标题】:Inner Join on 3 different tables在 3 个不同的表上进行内部联接
【发布时间】:2018-03-15 00:42:13
【问题描述】:

我需要从 3 个不同的表中提取数据。我们需要做的是从帖子表中提取帖子,其中发布帖子的用户被设置为公共用户,或者如果设置为私有,他们授予访问权限的用户可以查看他们的帖子。

这是表格:

user: id, username, name, password, email, private
posts: id, title, user, date, state
privateallowed: id, privateuser, alloweduser

这是我尝试获取记录的代码:

$username = $_COOKIE['username'];
$sqlposts = "select p.id, u.id, u.private, a.privateuser, a.alloweduser from user u 
                inner join posts p on u.id = p.user 
                    inner join privateallowed a on a.privateuser = u.id and a.alloweduser = " . $username . " 
                        where u.private='public' or (a.privateuser=p.user and a.alloweduser=" . $username . ")";
$resultpost = mysqli_query($dbcon, $sqlposts);
$numrows = mysqli_num_rows($resultpost);

很遗憾,没有返回任何记录。感谢您提供任何帮助或想法。

【问题讨论】:

  • 即使是最简单的查询也会返回任何记录吗?例如SELECT * FROM User?
  • 是的,如果我只是从任何表中进行简单的选择,它就可以正常工作。我认为问题出在连接的语法上,只是不确定在哪里。
  • 以下内容对我来说有点多余or (a.privateuser=p.user and a.alloweduser=" . $username . ")",因为您已经在u.id = p.user 上为表posts 执行INNER JOIN。因此,如果a.privateuser = u.id 那么a.privateuser = p.user
  • 感谢您的回复。在 php 中,点和变量之间的空格无关紧要。我会在早上试一试,让你知道这是否有效。
  • 字符串值需要用引号引起来,所以不要使用a.alloweduser = " . $username . ",而是尝试使用a.alloweduser = '" . $username . "'

标签: php sql join


【解决方案1】:

为了它的价值(@pngp 评论说需要在'" . $username . "' 周围加上单引号):

$username = $_COOKIE['username'];
$sqlposts = "SELECT p.id, u.id, u.private, a.privateuser, a.alloweduser 
             FROM user u 
             INNER JOIN posts p ON
                   u.id = p.user 
             INNER JOIN privateallowed a ON
                   a.privateuser = u.id AND a.alloweduser = '" . $username . "' 
             WHERE u.private='public';
        $resultpost = mysqli_query($dbcon, $sqlposts);
        $numrows = mysqli_num_rows($resultpost)";

另外请注意,我已经从您的WHERE 条件中删除了以下内容,因为之前的INNER JOIN 是多余的。我们只能推断出这一点,因为您使用了INNER JOIN,如果您使用了LEFT JOIN,则需要保持原样。

. . .or (a.privateuser=p.user and a.alloweduser=" . $username . ")"

解释:

  • INNER JOIN posts p ON u.id = p.user
    • 所以我们确定u.id = p.user
  • INNER JOIN privateallowed a ON a.privateuser = u.id
    • 所以我们推断a.privateuser = p.user
  • AND a.alloweduser = '" . $username . "'
    • 这涵盖了您的WHERE 中的剩余条件

【讨论】:

    【解决方案2】:

    我确实找到了答案,但我确信这不是一个完美的答案。我所做的是将语句分解为单独的 select 语句,然后在 where 子句中嵌入一个,如下所示:

     $sqlposts = "SELECT p.id, u.id, u.private 
            FROM user u 
            INNER JOIN posts p ON u.id = p.user 
            WHERE u.private='public' or p.user in 
            (
                select a.privateuser 
                from privateallowed a 
                inner join posts p on p.user = a.privateuser 
                where a.alloweduser=" . $username . "
            )";
    

    我和另一个精通 sql 的人看了几个小时,但我们无法选择返回正确的结果。我们尝试了以下方法,但由于某种原因,它返回了每个公共用户 3 次:

    SELECT p.id, u.id, u.private 
            FROM user u 
            INNER JOIN posts p ON u.id = p.user 
            INNER JOIN privateallowed a on a.alloweduser=24
            WHERE u.private='public' or p.user = a.privateuser
    

    感谢大家对此的帮助。如果有人有任何其他想法,我很感激他们。我正在开发一个我希望会增长的网站,并且我想确保页面加载速度尽可能快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-06
      • 2016-07-29
      • 2014-01-18
      • 1970-01-01
      • 2019-02-23
      • 1970-01-01
      • 1970-01-01
      • 2018-01-05
      相关资源
      最近更新 更多