2009-11-30 64 views
2

我面臨着一個關於處理我們項目中的線程註釋的決定... 我有一個簡單的MySQL表,它包含所有的註釋。有兩種類型:父母和孩子。孩子代表對父母或其他孩子的答覆。mySQL查詢中的條件限制可能嗎?

我的問題:

-Comment(深度0)
- 回覆兒童(深度1)
---回覆以前的孩子(深度2)
-Comment(深度0)

想象一下上面的結構和帶有LIMIT 2的MySQL查詢。它會削減最後一個回覆(深度2)。其實我想說的是這樣的:嘗試限制到2,如果孩子留下,直到下一個父母。試了幾個查詢,沒有運氣...

我已經把現在作爲遵循什麼:
選擇 SQL_CALC_FOUND_ROWS * FROM 評論 WHERE comment_post_id = '{$ _REQUEST [ 「ID」]}' ORDER BY COMMENT_ID,COM​​MENT_DATE DESC LIMIT 10"

重要的表中的字段有:
COMMENT_ID(指數)| comment_parent_id(含父母或NULL的COMMENT_ID)| comment_日期

我會非常感謝任何想法!

Saludos, Booosh

+0

是的一些架構和SQL信息將在這裏幫助。 – 2009-11-30 21:35:05

+0

'LIMIT 2'意味着查詢只返回2行;我收集你想要返回一個只有2個孩子深的列表? – 2009-11-30 21:35:32

+0

是的......好的更加精確: 重要表結構: comment_id | parent_coment id | COMMENT_DATE SQL查詢: SELECT SQL_CALC_FOUND_ROWS * FROM 評論 WHERE comment_post_id = '{$ _REQUEST [ 「ID」]}' ORDER BY COMMENT_ID, COMMENT_DATE DESC LIMIT 10 – Bosh 2009-11-30 21:56:11

回答

1

MySQL不具備任何功能解析樹狀結構。在最簡單的情況下(孩子具有父母的ID),您需要以編程方式遞歸到樹中以查找給定節點的所有子節點。 MaxLevel表示你想要去的深度。它隨遞歸調用遞減,以便在最後以0結束,這會停止遞歸。

例如(僞代碼)

findNodes(String parentId, int maxLevel) 
{ 
    select * from posts where parent = parentId 
    foreach (result...) 
    { 
    if (maxLevel > 0) 
    { 
     findNodes(result.nodeId, maxLevel - 1) 
    } 
    doSomethingWIthAResult 
    } 
} 

要以更加簡潔的方式做到這一點,有一些技術,所有這些都涉及某種形式的索引字段包含路徑任現職。路徑可能看起來像這樣:TopNode:Child1:Child2:Child3 ...在其中你可以做一個這樣的選擇 從類似於「TopNode%」和深度= 2的路徑中選擇*

+0

嘿爲THX答案..但實際上這對我來說很清楚,我已經有一個類似的功能來格式化和排序我的評論......也許我完全錯了,但是我想避免的是一次取得所有的評論。但要確保父母的所有孩子都被提取......我認爲子查詢可能是或多或少的解決方案......類似於所有父母一樣,限制到10歲並取回所有孩子...... – Bosh 2009-11-30 22:18:09

+0

只需挖多一點在mySQL documnetation ...也許我會找到一些東西 – Bosh 2009-11-30 22:19:13

1

總是想關於你真的想問數據庫的問題,然後然後把它翻譯成SQL - 在這種情況下,你想要「所有頂級評論與他們的直接子女列表(如果有的話)」。

例如。 (簡體)

SELECT * FROM comments c1 
LEFT JOIN comments c2 ON c2.parent_comment_id=c1.comment_id 
WHERE c1.parent_comment_id IS NULL 
ORDER BY c1.comment_date, c1.comment_id, c2.comment_date, c2.comment_id; 

與導致,你可以把它們寫出來以正確的順序 - 如果c2.comment_id爲null,它與沒有孩子的頂級評論,如果重複c1.comment_id,它的同一評論的另一個孩子。

+0

嗯,這就是我所說的啓示...不知道,我可以加入一個和同一個表本身...哇;-)我不知道這是否解決了我的極限問題,但我會試一試;)非常感謝! – Bosh 2009-11-30 22:25:58

0

我終於管理它基於格雷格Adamskis提示 ...所以不投我的回答,但檢查他的一個!

簡要描述問題...我們需要在我們的網站上發佈評論列表的分頁。使用標準限制可能會導致一些評論永遠不會顯示......我們需要的是一個限制,它隻影響我們的父節點,而不是影響節點的回覆......長話短說......但是也許有一次,這個iis很有用對於某人:

function getComments($comment_parent_id, $scope,&$comments, $db) 
    { 
     $res = $db->select("SELECT * FROM comments WHERE comment_post_id = '{$_REQUEST["ID"]}' AND comment_parent_id = '{$comment_parent_id}' ORDER BY comment_date DESC LIMIT {$scope}"); 

     while ($row = mysql_fetch_array($res, MYSQL_ASSOC)) 
     { 
      $i = count($comments)+1; 

      foreach ($row as $k => $v) { 
       $comments[$i][$k] = $v; 
      } 

      //LOOK FOR REPLIES (childs of parent) 
      if (mysql_num_rows($db->select("SELECT * FROM comments WHERE comment_parent_id = '{$row['comment_id']}' LIMIT 1")) != 0){ 
       getComments($row['comment_id'],100,$comments,$db); 
      } 
     } 
    } 

    //ARGUMENTS: parent_id (always starting with zero), scope, array holding comments, db class 
    getComments(0,5,$comments,$db); 
1

我面臨着同樣的問題,只有我只有一個深度。

--Comment (depth: 0) 
---Reply (depth: 1) 

我設法使用單個查詢來選擇所有這些記錄,同時限制頂級Comment記錄只有10

SELECT c.* FROM comments AS c WHERE c.OwnerId = 1 AND c.ParentId = 0 LIMIT 10 
UNION 
SELECT cc.* FROM comments AS cc 
    INNER JOIN 
    (
     SELECT CommentId FROM comments WHERE OwnerId = 1 AND ParentId = 0 LIMIT 10 
    ) 
    AS c2 
    ON cc.ParentId = c2.CommentId 

該查詢基本上執行以下操作:

  • 獲取頂級評論的前10條記錄,並具有 特定所有者標識。
  • 獲取所有具有與第一個查詢返回的 的註釋ID相同的父ID的註釋,並將它們結合到結果集中。

雖然我認爲這個查詢比爲每個記錄對數據庫進行多次調用更有效率,但它仍然具有執行第一個查詢兩次的缺陷。一次在工會之前,另一次在工會加入。

它似乎相當快,但沒有我想要的那麼快。但是,如果數據庫是遠程數據庫,並且延遲問題,則此解決方案可能比爲數據庫進行多個遠程查詢更好。

+0

你的例子幫助我解決了這個問題。在關閉INNER JOIN後,我必須改變它,雖然也向UNION Select添加條件。 – 2014-04-02 12:15:42