PHP mysql 连接 3 个表并在正确的位置显示正确的信息


PHP mysql Joining 3 tables and displaying the correct information in the right places

所以今天我需要帮助来连接三个表,我想我已经成功连接了它们,它们显示文本,但不是我想要的方式。

我希望它们像这样显示

在发布状态和时间戳

时写入状态和时间戳的用户的名称。这东西是正确的

状态 这也正确显示

在这里,我希望对状态的注释与编写它的用户的名称一起显示

我可以让评论显示在正确的状态上,但在所有其他状态下,评论中都会显示用户的名称,并且时间戳都相同,例如评论时间和状态时间相同。

这是我用来从MySQL获取信息的代码

$test5 ="SELECT status, 
    status.pubdate, 
    firstname,
    surname,
    komment,
    komment.pubdate 
FROM status 
INNER JOIN user ON status.user_id = user.user_id 
LEFT JOIN komment ON status.status_id = komment.status_id 
ORDER BY status.pubdate DESC";

这是它应该显示它的地方

$stmt = $db->prepare($test5);
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
    echo "<section class='statusar'>". "<b>".$row['firstname']." ".$row['surname']."<time>".$row['pubdate']."</time>"."</b>" ."<article>";
    echo $row['status'];
    echo "</article>";

        echo "<section class='komment'><b>".$row['firstname']." ".$row['surname']."<time>".$row['pubdate']."</time></b>"."<article>";
        echo $row['komment'];
        echo "</article></section></section>";
}

我试图做一个if(empty($row['komment'])但没有奏效,因为然后它在我也尝试!empty的框中做了一个评论框,这制作了更多的框

那么我如何让它在评论和状态上显示正确的时间,并使它们只显示有评论的状态评论,并为写评论的人显示正确的名称,我也尝试了$row['komment.pubdate']但随后它显示了一个错误

我希望你们明白如果不问我想做什么,我可以尝试更好地解释它

编辑

User TABLE    
user_id int unsigned AUTO_INCREMENT Primary index
firstname varchar 
surname varchar
username Unik 
password varchar
Status TABLE
status_id int unsigned auto_increment primary
user_id int unsigned index
status varchar
pubdate datetime
Komment TABLE
komment_id int unsigned auto_increment primary
status_id int unsigned index
user_id int unsgined index
komment varchar
pubdate datetime

所有表也有这样的关系

User Table          Status Table         Komment Table
 user_id---Relation---user_id--------------user_id
                     status_id------------status_id

编辑 2

所以现在我已经正确了一件事,所以如果帖子没有评论,它不会打印任何内容,但我仍然需要正确获取评论用户名,我仍然需要状态以显示正确的发布日期和评论以显示自己的发布日期

编辑 3

所以我修复了一件事,我添加了status.pubdate AS pubdate1,所以现在我可以显示状态更新自己的日期和评论自己的日期

但是我仍然有一些问题,例如如果我在用户 1s 帖子上添加用户 2 的评论,则不会显示评论,但是如果我在用户 2s 帖子上添加用户 2 的评论,然后会显示评论我不知道如何解决此帮助请!

编辑 4

没关系,现在我只需要修复一件事,那就是显示评论的正确用户名

我试图将名字和姓氏添加到注释表中,但是当我尝试在用户表和注释表之间建立关系时,它说了一些关于外键的信息

Error foreign key relation could not be added! #1452 - Cannot add or update a child row: a foreign key constraint fails (`projekt`.`#sql-15f8_8d7`, CONSTRAINT `#sql-15f8_8d7_ibfk_1` FOREIGN KEY (`firstname`) REFERENCES `komment` (`firstname`) ON DELETE CASCADE ON UPDATE CASCADE)

由于状态和评论的作者可以(很可能?)是不同的用户,因此您需要加入用户表两次。

SELECT 
    s.status_id
    s.status, 
    s.pubdate AS status_pubdate, 
    sa.firstname AS sa_firstname,
    sa.surname AS sa_surname,
    k.komment,
    k.pubdate AS komment_pubdate,
    ka.firstname AS ka_firstname,
    ka.surname AS ka_surname,
FROM 
    status s 
INNER JOIN user sa ON s.user_id = sa.user_id 
LEFT JOIN komment k ON s.status_id = k.status_id 
LEFT JOIN user ka ON k.user_id = ka.user_id 
ORDER BY s.pubdate DESC

请注意引入的表别名s(用于状态),sa(用于状态作者),k(用于komment)和ka(用于komment作者)。通过使用别名,可以联接同一个表两次,而不会产生冲突(不明确)的字段名称。上面的查询将用户表联接两次,sa保存状态的作者信息,ka komment 的作者信息。

这样,查询将为每个状态/注释组合检索一行数据。与您的处理代码一起使用很容易,IFF 每个状态只能有一个注释。

$stmt = $db->prepare($test5);
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
    echo "<section class='statusar'>". "<b>".$row['sa_firstname']." ".$row['sa_surname']."<time>".$row['status_pubdate']."</time>"."</b>" ."<article>";
    echo $row['status'];
    echo "</article>";
    echo "<section class='komment'><b>".$row['ka_firstname']." ".$row['ka_surname']."<time>".$row['komment_pubdate']."</time></b>"."<article>";
    echo $row['komment'];
    echo "</article></section></section>";
}

但是,我假设每个状态可以有多个评论。在这种情况下,您可能希望拆分查询。尽管如此,上述查询将起作用并检索所有状态的所有注释,但每个注释的状态信息将重复,这意味着您需要将处理代码更新为如下所示的内容:

$stmt = $db->prepare($test5);
$stmt->execute();
$last_processed_status_id = null;
$section_open = false;
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
    if ($row['status_id'] != $last_processed_status_id) {
        if ($section_open) { echo "</section>"; $section_open = false; }
        echo "<section class='statusar'>" . "<b>" . $row['sa_firstname'] . " " . $row['sa_surname'] . "<time>" . $row['status_pubdate'] . "</time>" . "</b>" . "<article>";
        echo $row['status'];
        echo "</article>";
        $last_processed_status_id = $row['status_id'];
        $section_open = true;
    }
    echo "<section class='komment'><b>".$row['ka_firstname']." ".$row['ka_surname']."<time>".$row['komment_pubdate']."</time></b>"."<article>";
    echo $row['komment'];
    echo "</article></section>";
}
if ($section_open) { echo "</section>"; }

使用左外连接

$test5="select a.firstname,a.surname,b.pubdate,c.pubdate 
from user a 
left outer join status b on a.user_id=b.user_id 
left outer join komment c on b.status_id=c.status_id 
order by b.pubdate";

像这样更新查询

$test5 ="SELECT status, 
    status.pubdate, 
    firstname,
    surname,
    komment,
    komment.pubdate 
FROM status 
INNER JOIN user ON status.user_id = user.user_id 
LEFT JOIN komment ON status.user_id = komment.user_id AND status.status_id = komment.status_id 
ORDER BY status.pubdate DESC";

选中左内部连接.. 添加一个条件.. status.user_id = komment.user_id

当您想要显示您的记录时,它将帮助美国。