示例 php 脚本(假设将数据库连接类传递给函数)。
<?php
post_replies($db, 0, 0);
function post_replies($db, $cnt=0, $parent_id=0)
{
$messages = array();
$sql = "SELECT id, message
FROM some_table
WHERE replyTo = ".(int)$parent_id."
ORDER BY date";
$results = $db->query($sql);
while($row = $db->fetch_assoc())
{
$messages[] = $row;
}
foreach($messages AS $message)
{
echo str_repeat("\t", $cnt).$message['message'];
post_replies($db, $cnt + 1, $message['id'])
}
}
?>
可以稍微调整一下,以避免对没有回复的消息进行进一步查询:-
<?php
post_replies($db, 0, 0);
function post_replies($db, $cnt=0, $parent_id=0)
{
$messages = array();
$sql = "SELECT a.id, a.message, COUNT(b.id) AS child_count
FROM some_table a
LEFT OUTER JOIN some_table b
ON a.id = b.parent_id
WHERE a.replyTo = ".(int)$parent_id."
GROUP BY a.id, a.message
ORDER BY a.date";
$results = $db->query($sql);
while($row = $db->fetch_assoc())
{
$messages[] = $row;
}
foreach($messages AS $message)
{
echo str_repeat("\t", $cnt).$message['message'];
if ($message['child_count'] > 0)
{
post_replies($db, $cnt + 1, $message['id'])
}
}
}
?>
编辑
想了想,决定玩一玩。由于您有最大数量的级别,这可能通过详细的 SQL 来实现。
这可以通过获取所有回复为 0 的消息,然后将其与所有回复为 0 和子记录的消息合并。并对大子记录等做同样的事情。
在排序上稍加修饰,这会使事情恢复到正确的顺序:-
SELECT a.date AS aDate, a.id AS aId,
b0.date AS b0Date, b0.id AS b0Id,
b1.date AS b1Date, b1.id AS b1Id,
b2.date AS b2Date, b2.id AS b2Id,
b3.date AS b3Date, b3.id AS b3Id,
b4.date AS b4Date, b4.id AS b4Id,
b5.date AS b5Date, b5.id AS b5Id,
b6.date AS b6Date, b6.id AS b6Id,
b7.date AS b7Date, b7.id AS b7Id,
b8.date AS b8Date, b8.id AS b8Id,
CONCAT(REPEAT('-', 9), b8.message)
FROM some_table a
INNER JOIN some_table b0 ON a.id = b0.replyTo
INNER JOIN some_table b1 ON b0.id = b1.replyTo
INNER JOIN some_table b2 ON b1.id = b2.replyTo
INNER JOIN some_table b3 ON b2.id = b3.replyTo
INNER JOIN some_table b4 ON b3.id = b4.replyTo
INNER JOIN some_table b5 ON b4.id = b5.replyTo
INNER JOIN some_table b6 ON b5.id = b6.replyTo
INNER JOIN some_table b7 ON b6.id = b7.replyTo
INNER JOIN some_table b8 ON b7.id = b8.replyTo
WHERE a.replyTo = 0
UNION ALL
SELECT a.date AS aDate, a.id AS aId,
b0.date AS b0Date, b0.id AS b0Id,
b1.date AS b1Date, b1.id AS b1Id,
b2.date AS b2Date, b2.id AS b2Id,
b3.date AS b3Date, b3.id AS b3Id,
b4.date AS b4Date, b4.id AS b4Id,
b5.date AS b5Date, b5.id AS b5Id,
b6.date AS b6Date, b6.id AS b6Id,
b7.date AS b7Date, b7.id AS b7Id,
NULL AS b8Date, NULL AS b8Id,
CONCAT(REPEAT('-', 8), b7.message)
FROM some_table a
INNER JOIN some_table b0 ON a.id = b0.replyTo
INNER JOIN some_table b1 ON b0.id = b1.replyTo
INNER JOIN some_table b2 ON b1.id = b2.replyTo
INNER JOIN some_table b3 ON b2.id = b3.replyTo
INNER JOIN some_table b4 ON b3.id = b4.replyTo
INNER JOIN some_table b5 ON b4.id = b5.replyTo
INNER JOIN some_table b6 ON b5.id = b6.replyTo
INNER JOIN some_table b7 ON b6.id = b7.replyTo
WHERE a.replyTo = 0
UNION ALL
SELECT a.date AS aDate, a.id AS aId,
b0.date AS b0Date, b0.id AS b0Id,
b1.date AS b1Date, b1.id AS b1Id,
b2.date AS b2Date, b2.id AS b2Id,
b3.date AS b3Date, b3.id AS b3Id,
b4.date AS b4Date, b4.id AS b4Id,
b5.date AS b5Date, b5.id AS b5Id,
b6.date AS b6Date, b6.id AS b6Id,
NULL AS b7Date, NULL AS b7Id,
NULL AS b8Date, NULL AS b8Id,
CONCAT(REPEAT('-', 7), b6.message)
FROM some_table a
INNER JOIN some_table b0 ON a.id = b0.replyTo
INNER JOIN some_table b1 ON b0.id = b1.replyTo
INNER JOIN some_table b2 ON b1.id = b2.replyTo
INNER JOIN some_table b3 ON b2.id = b3.replyTo
INNER JOIN some_table b4 ON b3.id = b4.replyTo
INNER JOIN some_table b5 ON b4.id = b5.replyTo
INNER JOIN some_table b6 ON b5.id = b6.replyTo
WHERE a.replyTo = 0
UNION ALL
SELECT a.date AS aDate, a.id AS aId,
b0.date AS b0Date, b0.id AS b0Id,
b1.date AS b1Date, b1.id AS b1Id,
b2.date AS b2Date, b2.id AS b2Id,
b3.date AS b3Date, b3.id AS b3Id,
b4.date AS b4Date, b4.id AS b4Id,
b5.date AS b5Date, b5.id AS b5Id,
NULL AS b6Date, NULL AS b6Id,
NULL AS b7Date, NULL AS b7Id,
NULL AS b8Date, NULL AS b8Id,
CONCAT(REPEAT('-', 6), b5.message)
FROM some_table a
INNER JOIN some_table b0 ON a.id = b0.replyTo
INNER JOIN some_table b1 ON b0.id = b1.replyTo
INNER JOIN some_table b2 ON b1.id = b2.replyTo
INNER JOIN some_table b3 ON b2.id = b3.replyTo
INNER JOIN some_table b4 ON b3.id = b4.replyTo
INNER JOIN some_table b5 ON b4.id = b5.replyTo
WHERE a.replyTo = 0
UNION ALL
SELECT a.date AS aDate, a.id AS aId,
b0.date AS b0Date, b0.id AS b0Id,
b1.date AS b1Date, b1.id AS b1Id,
b2.date AS b2Date, b2.id AS b2Id,
b3.date AS b3Date, b3.id AS b3Id,
b4.date AS b4Date, b4.id AS b4Id,
NULL AS b5Date, NULL AS b5Id,
NULL AS b6Date, NULL AS b6Id,
NULL AS b7Date, NULL AS b7Id,
NULL AS b8Date, NULL AS b8Id,
CONCAT(REPEAT('-', 5), b4.message)
FROM some_table a
INNER JOIN some_table b0 ON a.id = b0.replyTo
INNER JOIN some_table b1 ON b0.id = b1.replyTo
INNER JOIN some_table b2 ON b1.id = b2.replyTo
INNER JOIN some_table b3 ON b2.id = b3.replyTo
INNER JOIN some_table b4 ON b3.id = b4.replyTo
WHERE a.replyTo = 0
UNION ALL
SELECT a.date AS aDate, a.id AS aId,
b0.date AS b0Date, b0.id AS b0Id,
b1.date AS b1Date, b1.id AS b1Id,
b2.date AS b2Date, b2.id AS b2Id,
b3.date AS b3Date, b3.id AS b3Id,
NULL AS b4Date, NULL AS b4Id,
NULL AS b5Date, NULL AS b5Id,
NULL AS b6Date, NULL AS b6Id,
NULL AS b7Date, NULL AS b7Id,
NULL AS b8Date, NULL AS b8Id,
CONCAT(REPEAT('-', 4), b3.message)
FROM some_table a
INNER JOIN some_table b0 ON a.id = b0.replyTo
INNER JOIN some_table b1 ON b0.id = b1.replyTo
INNER JOIN some_table b2 ON b1.id = b2.replyTo
INNER JOIN some_table b3 ON b2.id = b3.replyTo
WHERE a.replyTo = 0
UNION ALL
SELECT a.date AS aDate, a.id AS aId,
b0.date AS b0Date, b0.id AS b0Id,
b1.date AS b1Date, b1.id AS b1Id,
b2.date AS b2Date, b2.id AS b2Id,
NULL AS b3Date, NULL AS b3Id,
NULL AS b4Date, NULL AS b4Id,
NULL AS b5Date, NULL AS b5Id,
NULL AS b6Date, NULL AS b6Id,
NULL AS b7Date, NULL AS b7Id,
NULL AS b8Date, NULL AS b8Id,
CONCAT(REPEAT('-', 3), b2.message)
FROM some_table a
INNER JOIN some_table b0 ON a.id = b0.replyTo
INNER JOIN some_table b1 ON b0.id = b1.replyTo
INNER JOIN some_table b2 ON b1.id = b2.replyTo
WHERE a.replyTo = 0
UNION ALL
SELECT a.date AS aDate, a.id AS aId,
b0.date AS b0Date, b0.id AS b0Id,
b1.date AS b1Date, b1.id AS b1Id,
NULL AS b2Date, NULL AS b2Id,
NULL AS b3Date, NULL AS b3Id,
NULL AS b4Date, NULL AS b4Id,
NULL AS b5Date, NULL AS b5Id,
NULL AS b6Date, NULL AS b6Id,
NULL AS b7Date, NULL AS b7Id,
NULL AS b8Date, NULL AS b8Id,
CONCAT(REPEAT('-', 2), b1.message)
FROM some_table a
INNER JOIN some_table b0 ON a.id = b0.replyTo
INNER JOIN some_table b1 ON b0.id = b1.replyTo
WHERE a.replyTo = 0
UNION ALL
SELECT a.date AS aDate, a.id AS aId,
b0.date AS b0Date, b0.id AS b0Id,
NULL AS b1Date, NULL AS b1Id,
NULL AS b2Date, NULL AS b2Id,
NULL AS b3Date, NULL AS b3Id,
NULL AS b4Date, NULL AS b4Id,
NULL AS b5Date, NULL AS b5Id,
NULL AS b6Date, NULL AS b6Id,
NULL AS b7Date, NULL AS b7Id,
NULL AS b8Date, NULL AS b8Id,
CONCAT(REPEAT('-', 1), b0.message)
FROM some_table a
INNER JOIN some_table b0 ON a.id = b0.replyTo
WHERE a.replyTo = 0
UNION ALL
SELECT a.date AS aDate, a.id AS aId,
NULL AS b0Date, NULL AS b0Id,
NULL AS b1Date, NULL AS b1Id,
NULL AS b2Date, NULL AS b2Id,
NULL AS b3Date, NULL AS b3Id,
NULL AS b4Date, NULL AS b4Id,
NULL AS b5Date, NULL AS b5Id,
NULL AS b6Date, NULL AS b6Id,
NULL AS b7Date, NULL AS b7Id,
NULL AS b8Date, NULL AS b8Id,
a.message
FROM some_table a
WHERE a.replyTo = 0
ORDER BY aDate DESC, aID,
IFNULL(b0Date, '2099-12-31') DESC, b0Id,
IFNULL(b1Date, '2099-12-31') DESC, b1Id,
IFNULL(b2Date, '2099-12-31') DESC, b2Id,
IFNULL(b3Date, '2099-12-31') DESC, b3Id,
IFNULL(b4Date, '2099-12-31') DESC, b4Id,
IFNULL(b5Date, '2099-12-31') DESC, b5Id,
IFNULL(b6Date, '2099-12-31') DESC, b6Id,
IFNULL(b7Date, '2099-12-31') DESC, b7Id,
IFNULL(b8Date, '2099-12-31') DESC, b8Id
它的 SQL 小提琴:-
http://www.sqlfiddle.com/#!2/775405/12