具有父子关系的注解的顺序分层查询?

jhiyze9q  于 2021-06-21  发布在  Mysql
关注(0)|答案(3)|浏览(463)

我有一个评论系统,使用 adjacency list 存储分层数据(我相信),例如:mysql表有列 id , parent_id , date , ... , 如果没有 parent_id 是主注解和带有 parent_id 自然是一个回答。
在初始页面加载时,我进行了一个ajax调用,该调用加载所有注解而不使用 parent_id ,所以所有的主要意见。 SELECT * FROM comms WHERE parent_id IS NULL 现在,如果任何一条评论有回复,就会出现一个类似于“加载回复”的按钮,然后单击另一个调用,加载所有有回复的评论 parent_id 那句话 id ,然后递归查询加载回复的回复等。这很管用,问题是从它们的加载顺序来看,你不能真正分辨什么是重播什么是重播。
所以我想要的是命令他们,以便重播下的评论,它属于。
现在,这是否只有通过sql才能实现 ORDER BY id = parent_id ,对它们进行排序,以便它们在某种程度上有意义,或者我应该从php处理这个问题?或者我应该重新开始以不同的方式储存它们?
编辑:第二个查询的一部分(示例取自我不久前找到的这个答案)

SELECT date_p, parent_id, id
   FROM (SELECT * FROM comms) rec,
   (SELECT @pv := 14) initialisation
   WHERE find_in_set(parent_id, @pv) > 0 
   AND @pv := concat(@pv, ',', id) ORDER BY ?

如果我使用我喜欢的答案中提供的“备选方案1”,那么订购方法会有所不同还是更好?
这就是我想要达到的目标:

<p>Main comm 1</p>
  <p>reply to main comm 1</p>
  <p>another reply to main comm 1</p>
    <p> replay to reply of main comm 1</p>
  <p> yet another reply to main comm 1</p>
<p>Main comm 2</p>
<p>Main comm 3</p>
i1icjdpr

i1icjdpr1#

因为这需要递归,而mysql pre v8并不真正支持这一点,所以我倾向于用擅长递归的php来解决这个问题。基本程序非常简单:

function show_children($db, $parent) {
    $sql = "SELECT * FROM comms WHERE parent_id " . ($parent ? "= $parent" : "IS NULL") . " ORDER BY date_p ASC";
    $result = $db->query($sql);
    if (!$result) return;
    while ($row = $result->fetch_assoc()) {
        echo "<p>" . $row['cmt'] . "</p>";
        show_children($db, $row['id']);
    }
}

show_children($db, 0);

从调用show\u children(parent\u id为0)开始,将获取所有顶级注解(parent\u id为null的注解),递归将按日期顺序显示所有答复,但也按它们的父级顺序显示(无论它们是注解还是答复)。
还可以添加“level”参数以允许设置输出样式:

function show_children($db, $parent, $level = 0) {
    $sql = "SELECT * FROM comms WHERE parent_id " . ($parent ? "= $parent" : "IS NULL") . " ORDER BY date_p ASC";
    $result = $db->query($sql);
    if (!$result) return;
    while ($row = $result->fetch_assoc()) {
        echo "<p class=\"level$level\">" . $row['cmt'] . "</p>";
        show_children($db, $row['id'], $level+1);
    }
}

show_children($db, 0);

注意,我假设mysqli是db接口。
使用此例程,使用此输入数据:

id  date_p      parent_id   cmt
1   2018-03-21  (null)      Main comm1
2   2018-03-22  (null)      Main comm2
3   2018-03-22  1           reply to main comm 1
4   2018-03-23  1           another reply to main comm 1
5   2018-03-23  1           yet another reply to main comm 1
6   2018-03-24  4           replay to reply of main comm 1
7   2018-03-24  (null)      Main comm3

您将得到以下输出:

<p class="level0">Main comm1</p>
<p class="level1">reply to main comm 1</p>
<p class="level1">another reply to main comm 1</p>
<p class="level2"> replay to reply of main comm 1</p>
<p class="level1"> yet another reply to main comm 1</p>
<p class="level0">Main comm2</p>
<p class="level0">Main comm3</p>
2w2cym1i

2w2cym1i2#

好问题:
你现在有个好主意:
我会把它放在3张不同的table上,
tb1)主要意见tb2)主要意见回复tb3)主要意见回复回复。
tb1包含像id(auto\ u increment)这样的列,成为您的主注解id
tb2)包含id(自动增量)、main注解id、reply to main注解id等列
tb3)具有id(自动增量)、主注解id、回复到主注解id、回复回复id

<p1>main_comment_id</p1>
  <p2>reply_to_main_comment_id</p2>
     <p3>reply_reply_id</p3>

logically like the following:

    if(p1){
       post to tb1
    }elseif(p2){
       post to tb2
    }elseif(p3){
       post to tb3
    }

To get the comments for p1, (Select comments from tb1)
To get comments for p2, (Select comments from tb2 where main_comment_id=$id)
To get comments for p3, (Select comments from tb3 where main_comment_id=$id 
 and reply_to_main_comment_id=$id2)

$sql ("SELECT comments from tb3 WHERE main_comment_id=$id1 AND reply_to_main_comment_id=$id2 ORDER BY date DESC");

当然,当你调用你的评论时,你会按时间顺序显示它们,从最新到最旧,你的p2成为p3的主要评论。。它就像一个父母和一个孩子,但你显示它在一个扩展的关系方式…这将只是在正确的地方的评论。。。。
希望这能奏效。我没有测试过这个,但我开发了一个具有类似原理的数据库。。。。
获取主要注解的代码示例:

$comment1 = $_POST['comment1'];
$comment1_sql = ("Insert INTO tb1 (main_comment) VALUES ($comment1)");
$comment_result = mysqli_query($conn, $comment_sql1);

代码示例回复主要注解:

$comment2 = $_POST['comment2'];
$comment2_sql = ("Insert INTO tb2 (reply_to_main_comment) VALUES ($comment2)");
$comment_result = mysqli_query($conn, $comment_sql2);

同意见回复回复回复的主要意见

0pizxfdo

0pizxfdo3#

我在mssql工作,我非常肯定交叉应用将帮助你。我假设mysql确实有这个连接。

SELECT A.PARENT_ID,A.COMMENT,* FROM T A 
CROSS APPLY T B 
where a.id = 3

相关问题