簡體   English   中英

訂購帶有父子關系的注釋的分層查詢?

[英]Order hierarchical query for comments with parent-child relation?

我有一個使用adjacency list存儲層次結構數據的注釋系統(我相信),例如:MySql表具有idparent_iddate ,...列,其中沒有parent_id的注釋是主要注釋和注釋與parent_id自然是一個答復。

在初始頁面加載時,我進行Ajax調用,該加載將加載所有注釋,而無需parent_id ,因此所有主要注釋都將被加載。

SELECT * FROM comms WHERE parent_id IS NULL

現在,如果任何評論都有回復,則該評論會出現一個類似“ load replies”的按鈕,並且在單擊時會進行另一個調用,以加載所有具有該id parent_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>

由於這需要遞歸,而MySQL pre v8並不真正支持該遞歸,因此我傾向於解決PHP中的問題,因為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);

從對parent_id為0的show_children的調用開始,將獲取所有頂級注釋(parent_id = NULL的那些注釋),並且遞歸將按日期順序顯示所有答復,但也將按其父母的順序顯示所有答復(無論是否為評論或回復)。

您還可以添加“級別”參數以允許設置輸出的樣式:

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作為數據庫接口。

使用此例程,並使用以下輸入數據:

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>

好問題:

您現在擁有的是一個好主意:

我會將其存儲在3個不同的表中,

tb1)代表主評論tb2)代表主評論回復tb3)代表主評論回復。

tb1包含ID(auto_increment)之類的列成為您的主要評論ID

tb2)包含id(auto_increment),main_comment_id,reply_to_main_comment_id之類的列

tb3)具有id(auto_increment),main_comment_id,reply_to_main_comment_id,reply_reply_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);

與評論回復相同,對主要評論的回復

我使用MSSQL,我非常相信CROSS APPLY將為您提供幫助。 我假設MYSQL確實具有該join。

例如

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM