RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 553123
Accepted
sanu
sanu
Asked:2020-08-08 20:19:30 +0000 UTC2020-08-08 20:19:30 +0000 UTC 2020-08-08 20:19:30 +0000 UTC

如何正确组织树形结构中子评论的提取?

  • 772

我发表评论,它们应该是树状的,并且只有一层嵌套(请注意 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

但是这个选项虽然有效,但很糟糕,因此需要更正确的解决方案....

mysql
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. A K
    2020-08-08T21:13:07Z2020-08-08T21:13:07Z

    关于您的问题,我推荐以下几个链接:

    • 关于 Netsted Set for mysql http://habrahabr.ru/post/153861
    • 构建树的三种基本算法:http: //habrahabr.ru/post/46659

    数据库中的数据结构选择正确:AL 是最合适的。

    一般来说,既然你总是有两个最后的评论:使用mysql的limit 0, 1和limit 1,1特性来获取你的评论,不用担心切换到NS。

    进一步来说。使用两个查询。选择按日期排序的子评论。在第一个请求限制 0,1(最后一条评论),在第二个请求限制 1,1(倒数第二条评论。满意吗?

    SELECT
      `c1`.`id`,
      `c1`.`pid`,
      (SELECT id FROM `_fx_comments` AS `c` WHERE `c`.`pid` = `c1`.`id`  ORDER BY `date` DESC LIMIT 0,1) AS last_comment,
      (SELECT id FROM `_fx_comments` AS `c` WHERE `c`.`pid` = `c1`.`id`  ORDER BY `date` DESC LIMIT 1,1) AS prev_last_comment      
    
    FROM `_fx_comments` AS `c1`
    WHERE 1 = 1
    

    在这里,您将获得所需记录的 ID(如果没有记录,则为 NULL)。

    针对您的具体问题的解决方案。适合?

    • 2
  2. Best Answer
    Mike
    2020-08-09T15:54:52Z2020-08-09T15:54:52Z

    你可以想象这样的事情:

    select *
      from (
            select if(N=1,    id,
                   if(N=2,  l_id,
                           ll_id)) id,
                   id as P_ID,
                   N
              from (select id,
                           (select id from _fx_comments L
                             where L.pid=C.id
                             order by date desc limit 0,1) as l_id,
                           (select id from _fx_comments L
                             where L.pid=C.id
                             order by date desc limit 1,1) as ll_id
                      from _fx_comments C
                     where pid is null
                     order by date desc
                     limit 10) A,
                    (select 1 as N union select 2 union select 3) B
        ) A
     inner join _fx_comments fx_cmt on fx_cmt.id=A.id
      left 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
     order by P_ID, N
    

    主子查询的任务是获取最后 10 条评论的 ID,以及紧挨着它们的最后和倒数第二个子评论的 ID。之后,将其乘以请求发布编号 1、2、3。接下来,IF 将所有接收到的 ID 垂直扩展为一列。为此,您已经可以从评论和其他表格中粘贴基本信息。为了方便引用子查询对最终输出进行排序,可以返回排序所需要的任意列(例子中P_ID)加上数字N,通过这个数字最终的顺序就会明白什么是一级评论,什么是它的孩子们。

    • 1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何停止编写糟糕的代码?

    • 3 个回答
  • Marko Smith

    onCreateView 方法重构

    • 1 个回答
  • Marko Smith

    通用还是非通用

    • 2 个回答
  • Marko Smith

    如何访问 jQuery 中的列

    • 1 个回答
  • Marko Smith

    *.tga 文件的组重命名(3620 个)

    • 1 个回答
  • Marko Smith

    内存分配列表C#

    • 1 个回答
  • Marko Smith

    常规赛适度贪婪

    • 1 个回答
  • Marko Smith

    如何制作自己的自动完成/自动更正?

    • 1 个回答
  • Marko Smith

    选择斐波那契数列

    • 2 个回答
  • Marko Smith

    所有 API 版本中的通用权限代码

    • 2 个回答
  • Martin Hope
    jfs *(星号)和 ** 双星号在 Python 中是什么意思? 2020-11-23 05:07:40 +0000 UTC
  • Martin Hope
    hwak 哪个孩子调用了父母的静态方法?还是不可能完成的任务? 2020-11-18 16:30:55 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    Arch ArrayList 与 LinkedList 的区别? 2020-09-20 02:42:49 +0000 UTC
  • Martin Hope
    iluxa1810 哪个更正确使用:if () 或 try-catch? 2020-08-23 18:56:13 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5