【问题标题】:Joining a 3rd MySQL table (redone)加入第三个 MySQL 表(重做)
【发布时间】:2014-06-29 06:58:42
【问题描述】:

好的,所以我将尝试重新解释这个问题,因为似乎没有人理解我的目的。现在是凌晨 3 点,所以这可能是我有点松懈的地方……但我会在这里尽力而为。

我目前正在开发一个帖子和评论部分,用户可以在他们自己或其他用户的墙上发帖,因此其他用户可以对这些帖子发表评论。与社交网络状态或一般论坛相同。我有 3 张桌子...

Users
Statuses
Comments

用户包含标准...

userid
username
first_name
last_name
photo

状态包含有关每个用户发布的主要状态的任何信息,这些状态显示在用户个人资料中。因此,用户 1 可以在用户 2 的个人资料上发布状态。这是状态表设计...

status_id (auto-i)
user_id (The users ID whos profile the post was added too)
sender_id (The user who sent the post or wrote it)
date (Date/Time was sent)
rate (This doesn't matter for a moment)
comments (This will count all the comments and display the number)
status (The actual status written out)

这些表在我的脚本中一起工作得很好,该脚本连接了两个表并显示了用户信息(发布状态的人),例如他们的个人资料照片和姓名等...这是我当前的脚本,在所有...

//// GET STATUSES
                                    $user_id = $profile_data['userid'];
                              $data = mysql_query("
                              SELECT 
                     statuses.status_id, 
                     statuses.user_id,
                     statuses.sender_id,
                     statuses.date,
                     statuses.rate,
                     statuses.comments,
                     statuses.status,
                     users.userid, 
                     users.username, 
                     users.first_name, 
                     users.last_name, 
                     users.photo
                              FROM 
                                    statuses
                              LEFT JOIN 
                                    users
                              ON 
                                    statuses.sender_id=users.userid
                              WHERE 
                                    statuses.user_id = '{$profile_data['userid']}' 
                              ORDER BY 
                              `statuses`.`date` DESC
                               ") or die(mysql_error());  

                                  while($status = mysql_fetch_array( $data ))//added this
                                  {
                                  $statusid = $status['status_id'];
                                  $date = $status['date'];
                                  $rate = $status['rate'];
                                  $comments = $status['comments'];
                                  $userid = $status['user_id'];
                                  $senderid = $status['sender_id'];
                                  $statusbody = $status['status'];
                                  $username = $status['username'];
                                  $firstname = $status['first_name'];
                                  $lastname = $status['last_name'];
                                  $photo = $status['photo'];

                                  ?>
<form action="" method="POST" role="form" enctype="multipart/form-data" id="statusupdate" class="facebook-share-box">
            <div class="share">
                <div class="panel panel-default">
                      <div class="panel-heading"><a href="<? echo 'http://basecentre.co.uk/',$status["username"]; ?>"><img alt="" align="left" hspace="20" height="70" width="70" src="<? echo 'http://basecentre.co.uk/userimages/',$status["photo"]; ?>"> </a> <font size="+2"><i class="icon icon-comment-o"></i></font> <a href="<? echo 'http://basecentre.co.uk/',$status["username"]; ?>"><font size="+2"><?php echo $status['first_name']; ?> <?php echo $status['last_name'] ; ?></font></a> | <i class="icon icon-clock-o"></i> <a rel="tooltip" href="#" data-original-title="<? echo "". date('F j, Y, g:i a', strtotime($status['date']) + 60*60) .""; ?>"><?php echo "<strong>". date('j F', strtotime($status['date']) + 60*60) ."</strong>"; ?></a></div>
                      <div class="panel-body">
                        <div class="">
                            <?php echo $status['status']; ?>
                        </div>
                      </div>
                        <div class="panel-footer">
                                <div class="row">
                                <div class="col-md-7">
                                Comment | Like
                                </div>
                                </div>
                        </div>
                    </div>
            </div>
        </form>
                               </br>


<? 
                                  }


    ?>  

我为 cmets 建立了一个新表。所以我可以去一个用户个人资料,阅读一个“状态”,然后我可以给它添加评论......这是那个新表......

comment_id (auto-i)
status_id (added depending on which status you comment on. If the comment is on status id #5, the same number will be sent to this to connect the comments with the correct statuses)
sender_id (the id of the user who is sending the comment which would be $_session['userid'];
date (date the comment was sent)
rate (Doesn't matter yet)
comment (the actual comment written out).

我需要将新的 cmets 表加入到其他两个表中,不知何故?我尝试添加另一个“左连接”,但没有奏效?而且我对这些东西不太擅长。 我的目标是让每条评论按照发布日期的顺序正确显示在其连接状态上。最近在底部...显示用户信息,以便您知道谁发表了评论。

希望这能给你更多的理解,我希望有人能提供帮助!!抱歉,它很长,但是你们要求提供更多信息...谢谢!

编辑添加数据库记录:

状态表:

CREATE TABLE IF NOT EXISTS `statuses` (
  `status_id` int(25) NOT NULL AUTO_INCREMENT,
  `user_id` int(25) NOT NULL,
  `sender_id` int(25) NOT NULL,
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `rate` int(25) NOT NULL DEFAULT '0',
  `comments` int(25) NOT NULL DEFAULT '0',
  `status` text COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`status_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=30 ;

--
-- Dumping data for table `statuses`
--

INSERT INTO `statuses` (`status_id`, `user_id`, `sender_id`, `date`, `rate`, `comments`, `status`) VALUES
(15, 11, 22, '2014-05-11 21:22:00', 0, 0, 'This is pretty damn cool! '),
(16, 11, 91, '2014-05-11 21:22:35', 0, 0, 'LOL how did you do this shit man?? Alll you gotta do now is add the comments ;) and likes! '),
(14, 11, 22, '2014-05-11 21:21:35', 0, 0, 'Hey budddy how are ya ? '),
(13, 11, 11, '2014-05-11 21:18:10', 0, 0, 'eerer'),
(11, 11, 11, '2014-05-11 21:10:33', 0, 0, 'Ho Ho!'),
(10, 11, 11, '2014-05-11 21:10:27', 0, 0, 'Hey hey ! '),
(28, 11, 11, '2014-05-12 00:47:02', 0, 0, 'LOL just another quick test ;) '),
(29, 22, 22, '2014-05-12 02:30:44', 0, 0, 'I should be able to delete this status... '),
(20, 11, 11, '2014-05-11 21:30:17', 0, 0, 'LOL WINNER'),
(21, 22, 11, '2014-05-11 23:31:18', 0, 0, 'Hey mate :D '),

(19, 11, 11, '2014-05-11 21:24:47', 0, 0, 'Not bad eh guys? ;P ');

评论表:

--
-- Table structure for table `comments`
--

CREATE TABLE IF NOT EXISTS `comments` (
  `comment_id` int(100) NOT NULL AUTO_INCREMENT,
  `status_id` int(25) NOT NULL,
  `user_id` int(25) NOT NULL,
  `sender_id` int(25) NOT NULL,
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `rate` int(25) NOT NULL DEFAULT '0',
  `comment` text COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`comment_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ;

--
-- Dumping data for table `comments`
--

INSERT INTO `comments` (`comment_id`, `status_id`, `user_id`, `sender_id`, `date`, `rate`, `comment`) VALUES
(1, 28, 11, 11, '2014-05-12 01:23:58', 0, 'Hmmm shall we see if we can get this working too!? Comments, here we come! '),
(2, 28, 11, 22, '2014-05-12 02:55:33', 0, 'This is not aidans comment! another username should appear!');

用户表:

    CREATE TABLE IF NOT EXISTS `users` (
  `userid` int(25) NOT NULL AUTO_INCREMENT,
  `first_name` varchar(25) COLLATE latin1_general_ci NOT NULL,
  `middle_name` varchar(25) COLLATE latin1_general_ci NOT NULL,
  `last_name` varchar(25) COLLATE latin1_general_ci NOT NULL,
  `email_address` varchar(50) COLLATE latin1_general_ci NOT NULL,
  `username` varchar(25) COLLATE latin1_general_ci NOT NULL,
  `password` varchar(255) COLLATE latin1_general_ci NOT NULL,
  `photo` varchar(50) COLLATE latin1_general_ci NOT NULL DEFAULT 'default.png',
  `date1` varchar(25) COLLATE latin1_general_ci NOT NULL,
  `date2` varchar(25) COLLATE latin1_general_ci NOT NULL,
  `date3` varchar(25) COLLATE latin1_general_ci NOT NULL,
  `birthplace` varchar(50) COLLATE latin1_general_ci NOT NULL,
  `gender` varchar(25) COLLATE latin1_general_ci NOT NULL,
  `about` varchar(250) COLLATE latin1_general_ci NOT NULL DEFAULT 'This information has not yet been updated.',
  `user_level` enum('0','1','2','3','4') COLLATE latin1_general_ci NOT NULL DEFAULT '0',
  `signup_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `last_login` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `activated` enum('0','1') COLLATE latin1_general_ci NOT NULL DEFAULT '0',
  `location` varchar(30) COLLATE latin1_general_ci NOT NULL,
  `premium` enum('0','1') COLLATE latin1_general_ci NOT NULL DEFAULT '0',
  `blocked` varchar(5) COLLATE latin1_general_ci NOT NULL DEFAULT '0',
  `fr_alert` varchar(6) COLLATE latin1_general_ci NOT NULL DEFAULT '0',
  `um_alert` varchar(6) COLLATE latin1_general_ci NOT NULL DEFAULT '0',
  PRIMARY KEY (`userid`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci COMMENT='Membership Information' AUTO_INCREMENT=92 ;

【问题讨论】:

  • 您只希望显示有评论的帖子吗?还是你想要一些没有 cmets 的?
  • 我们需要查看您当前的查询
  • 我希望所有帖子都显示有或没有 cmets。
  • 我当前的查询在帖子中

标签: php html mysql


【解决方案1】:

大概是这样的吧?不完全确定您的数据是什么样子,所以它可能是错误的.. 加入发送评论和状态 ID 的用户,然后按评论 DATE desc 然后状态 DATE desc 排序,这样它最多会提供最新的 cmets最近的帖子

SELECT -- added alias to your tables so its easier to read
    s.status_id, 
    s.user_id,
    s.sender_id,
    s.date,
    s.rate,
    s.comments as s_comment,
    s.status,
    u.userid as u_id, 
    u.username as u_name, 
    u.first_name as u_first, 
    u.last_name as u_last, 
    u.photo as u_photo,
    o.userid as o_id, 
    o.username as o_name, 
    o.first_name as o_first, 
    o.last_name as o_last, 
    o.photo as o_photo,
    c.comment as c_comment
FROM statuses s
LEFT JOIN users u ON s.sender_id=u.userid
LEFT JOIN comments c ON c.user_id = u.userid AND c.status_id = s.status_id
LEFT JOIN users o on o.userid = c.sender_id
WHERE s.user_id = '{$profile_data['userid']}' 
ORDER BY c.date DESC, s.date DESC

试一试,让我知道有什么问题。如果你可以用几行实际数据编辑你的帖子,比如一些带有一些帖子和状态的 cmets,就像一个虚拟用户一样,我可以自己测试并澄清(会更容易)

【讨论】:

  • 我收到一条错误消息“不是唯一的表/别名:'o'”这是因为用户 o 与 'u' 相同吗?
  • 为每个表名使用别名再试一次。我认为它试图组合类似的列(具有相同的列名)
  • 除了显示每个人的个人资料上的所有帖子外,它还能正常工作吗?在 cmets 都意味着处于该状态的情况下,它会两次显示该状态,并且对每个状态都有不同的评论?
  • where 子句应该过滤掉其他用户.. 我做了另一个编辑让你试试.. 我写它是为了为每个评论显示不同的行...你想要一个新列吗每个带有用户名和 id 的 cmets 和东西?因为要做到这一点,您必须在选择的每一列中手动写入。
  • 从这里您所要做的就是获取数据.. 循环遍历它,如果多行的状态 ID 相同,则拉出 cmets 并添加到一个状态行...即做到这一点的最佳方法
【解决方案2】:

这个答案稍微改变了一些表结构,但背后的核心思想是一样的。

使用我在这里创建的示例 http://sqlfiddle.com/#!2/c1fa6e/1

所以基本上你可以对users 表进行两次INNER JOIN(两个表的结果)users 表,并使用AS 运算符为它们创建别名。这使您可以加入用户反对它以获取配置文件所有者信息,以及发布状态的人的信息。 (下面的示例仅显示在个人资料所有者 #1 上发布的状态)

SELECT status.status_id, 
  profile_owner.username AS owner, 
  status_sender.username AS sender
  FROM status
  INNER JOIN users AS profile_owner
    ON profile_owner.user_id = status.user_id
  INNER JOIN users AS status_sender
    ON status_sender.user_id = status.sender_id
  WHERE profile_owner.user_id = 1;

结果

STATUS_ID OWNER     SENDER
1         User 1    User 2
2         User 1    User 4

然后添加 cmets,你 LEFT JOIN cmets 表(可能并不总是有 cmets,在这种情况下这些字段将为空),然后要获取评论者的用户详细信息我们 INNER JOIN 再次用户表,针对评论者 ID 获取他们的详细信息

SELECT status.status_id, 
  profile_owner.username AS owner, 
  status_sender.username AS sender,
  status.status,
  status_comment.comment_body,
  commentor.username AS commentor
  FROM status
  INNER JOIN users AS profile_owner
    ON profile_owner.user_id = status.user_id
  INNER JOIN users AS status_sender
    ON status_sender.user_id = status.sender_id
  LEFT JOIN status_comment
    ON status.status_id = status_comment.status_id
  LEFT JOIN users AS commentor
    ON status_comment.commentor_id = commentor.user_id
  WHERE profile_owner.user_id = 1;

给出这些结果

STATUS_ID OWNER    SENDER  STATUS                         COMMENT_BODY                          COMMENTOR
1         User 1   User 2  Test status on User1 by User2  User3 commenting on status by User2.  User 3
1         User 1   User 2  Test status on User1 by User2  User4 commenting on status by User2.  User 4
2         User 1   User 4  Test status on User1 by User4  (null)  (null)

这表明 User1 在其个人资料上发布了 2 个状态,一个是 User2 的状态,有 2 个 cmets,另一个是 User4 的,没有 cmets。然后,您可以在 PHP 中解析这些结果并正确显示。

一旦你分解它,它就相当简单了。

你可以view it all in action here and play with it yourself on sqlfiddle

更新:使用您在帖子中编辑的数据库信息,I have created an SQLFiddle 尝试向您展示如何将其应用于现有数据库。

这很简单,您似乎只是将我的示例翻译成您的代码略有错误。以下是更改了相应表名的正确查询。

SELECT statuses.status_id, 
  profile_owner.first_name AS owner, 
  status_sender.first_name AS sender,
  statuses.status,
  comments.comment,
  commentor.first_name AS commentor
  FROM statuses
  INNER JOIN users AS profile_owner
    ON profile_owner.userid = statuses.user_id
  INNER JOIN users AS status_sender
    ON status_sender.userid = statuses.sender_id
  LEFT JOIN comments
    ON statuses.status_id = comments.status_id
  LEFT JOIN users AS commentor
    ON comments.sender_id = commentor.userid
  WHERE profile_owner.userid = 11;

这会提取用户 id 11 的个人资料上发布的所有状态。它还会提取这些状态可能具有的任何 cmets。

**附带说明...**我不确定您为什么将sender_iduser_id 存储在comments 表中。您的评论已经与某个状态相关,因此您知道它是针对谁发布的,您只需要存储发表评论的人。

尝试将每个实体视为它自己的对象。

你有 3 个对象

  • 用户
  • 状态
  • 评论

一个状态有一个发布它的用户 (status.user_id) 和发布它的用户 (status.sender_id)。

评论具有发布针对 (comments.status_id) 的状态以及发布评论的用户 (comments.sender_id)。

无需在 cmets 表中再次存储 status.userid,因为您可以随时加入它以获取该信息。

【讨论】:

  • 感谢您的帮助!这是我一直在寻找的东西,可以让我更好地了解连接表!虽然,在我的原始查询中,我从查询中列出了变量(即:statuses.status_id、status.user_id、users.userid、users.photo 等),我将在哪里将其合并到您的查询中以使用变量返回 "$status['photo']" 还是什么?
  • SELECT 语句中,您可以定义要作为查询的一部分返回的列。在我们的示例中,因为我们有名称相同的字段(例如usernames),所以我使用了AS 别名运算符来实质上重命名结果集中的该列。因此,要为个人资料用户提取photo 列,您可以在选择中添加类似这样的内容:profile_owner.photo AS profile_owner_photo,然后您可以使用$status['profile_owner_photo']
  • 我刚刚测试了它并且有一个错误说“表'u634727706_bc.status_comment'不存在”不知道为什么,因为它们都存在?
  • 你能把你用来测试它的代码连同完整的错误信息一起粘贴到pastebin.com
  • 完整的错误信息就是我上面写的,就是这么说的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-09
  • 1970-01-01
  • 2020-03-02
  • 1970-01-01
  • 2015-09-06
相关资源
最近更新 更多