我发表评论,它们应该是树状的,并且只有一层嵌套(请注意 YouTube 上的评论)。
表结构
CREATE TABLE `_fx_comments` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pid` int(11) DEFAULT NULL,
`sender` int(11) NOT NULL,
`recipient` int(11) DEFAULT NULL,
`target` varchar(150) NOT NULL,
`eid` int(11) NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`text` text,
`rateTrue` int(7) NOT NULL DEFAULT '0',
`rateFalse` int(7) NOT NULL DEFAULT '0',
`resource` text,
`approve` int(1) NOT NULL DEFAULT '1',
`isDel` int(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
KEY `pid` (`pid`),
KEY `sender` (`sender`),
KEY `recipient` (`recipient`),
KEY `target` (`target`),
KEY `eid` (`eid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
eid- 评论所属元素的pidid, - 父评论的id
我需要解决的主要任务是提取,比方说,最后 10 条评论有pid IS NOT NULL,并以某种方式查看当前评论是否有孩子,然后提取它们(两个孩子是最后添加的)。
但是现在我们需要以某种方式提取最后两个孩子.....有一个使用 NESTED SET 的想法,但我不知道如何在我的示例中应用它。
更新:
目前,有这样一个糟糕的解决问题的方法:
SELECT fx_cmt.id,fx_cmt.pid,fx_cmt.eid,fx_cmt.sender,fx_cmt.recipient,fx_cmt.date,fx_cmt.text,fx_cmt.rateTrue,fx_cmt.rateFalse,fx_cmt.resource,
fx_u.fx_login AS senderLogin, fx_u2.fx_login AS recipientLogin,
(SELECT COUNT(fx_cmt_count.id) FROM _fx_comments fx_cmt_count WHERE fx_cmt_count.pid = fx_cmt.id) AS countChilds,
fx_cmt_l.id AS lcId, fx_cmt_l.pid AS lcPid, fx_cmt_l.eid AS lcEid, fx_cmt_l.sender AS lcSender, fx_cmt_l.recipient AS lcRecipient, fx_cmt_l.date AS lcDate,
fx_cmt_l.text AS lcText, fx_cmt_l.rateTrue AS lcRateTrue, fx_cmt_l.rateFalse AS lcRateFalse, fx_cmt_l.resource AS lcResource,
fx_cmt_pl.id AS plcId, fx_cmt_pl.pid AS plcPid, fx_cmt_pl.eid AS plcEid, fx_cmt_pl.sender AS plcSender, fx_cmt_pl.recipient AS plcRecipient, fx_cmt_pl.date AS plcDate,
fx_cmt_pl.text AS plcText, fx_cmt_pl.rateTrue AS plcRateTrue, fx_cmt_pl.rateFalse AS plcRateFalse, fx_cmt_pl.resource AS plcResource,
fx_u_l.fx_login AS lcSenderLogin, fx_u2_l.fx_login AS lcRecipientLogin,
fx_u_pl.fx_login AS plcSenderLogin, fx_u2_pl.fx_login AS plcRecipientLogin
FROM _fx_comments AS fx_cmt
INNER JOIN _fx_users fx_u ON fx_u.id = fx_cmt.sender
LEFT JOIN _fx_users fx_u2 ON fx_u2.id = fx_cmt.recipient
LEFT JOIN _fx_comments fx_cmt_l ON fx_cmt_l.id = (SELECT id FROM _fx_comments AS c WHERE c.pid = fx_cmt.id ORDER BY date DESC LIMIT 0,1)
LEFT JOIN _fx_comments fx_cmt_pl ON fx_cmt_pl.id = (SELECT id FROM _fx_comments AS c WHERE c.pid = fx_cmt.id ORDER BY date DESC LIMIT 1,1)
LEFT JOIN _fx_users fx_u_l ON fx_u_l.id = fx_cmt_l.sender
LEFT JOIN _fx_users fx_u2_l ON fx_u2_l.id = fx_cmt_l.recipient
LEFT JOIN _fx_users fx_u_pl ON fx_u_pl.id = fx_cmt_pl.sender
LEFT JOIN _fx_users fx_u2_pl ON fx_u2_pl.id = fx_cmt_pl.recipient
WHERE fx_cmt.eid = 1
但是这个选项虽然有效,但很糟糕,因此需要更正确的解决方案....
关于您的问题,我推荐以下几个链接:
数据库中的数据结构选择正确:AL 是最合适的。
一般来说,既然你总是有两个最后的评论:使用mysql的limit 0, 1和limit 1,1特性来获取你的评论,不用担心切换到NS。
进一步来说。使用两个查询。选择按日期排序的子评论。在第一个请求限制 0,1(最后一条评论),在第二个请求限制 1,1(倒数第二条评论。满意吗?
在这里,您将获得所需记录的 ID(如果没有记录,则为 NULL)。
针对您的具体问题的解决方案。适合?
你可以想象这样的事情:
主子查询的任务是获取最后 10 条评论的 ID,以及紧挨着它们的最后和倒数第二个子评论的 ID。之后,将其乘以请求发布编号 1、2、3。接下来,IF 将所有接收到的 ID 垂直扩展为一列。为此,您已经可以从评论和其他表格中粘贴基本信息。为了方便引用子查询对最终输出进行排序,可以返回排序所需要的任意列(例子中P_ID)加上数字N,通过这个数字最终的顺序就会明白什么是一级评论,什么是它的孩子们。