【问题标题】:Grouping rows together with the same parent-ID将具有相同父 ID 的行分组在一起
【发布时间】:2025-11-25 02:05:01
【问题描述】:

我正在编写一个私人消息脚本。但是,我在 MySQL 端遇到了一些问题。我已经部分工作了。

一个例子:

messageid | parentid | subject | flags
1           NULL       'Foobar'  2     //has been read
2           1          'Foobar'  2     //has been read
3           1          'Foobar'  1     //has not been read

messageid:消息的自动递增
parentid:主题中第一条消息的messageid
主题: 主题(或标题)
标志: 位标志(1 = 未读;2 = 已读)

问题(希望有人能帮我解决)
1.我现在设置的方式,我的脚本将在未读消息页面和已读消息页面中显示消息线程。我的目标是让它在被阅读之前只显示在未读消息页面中。

这是我的查询

//$_GET['node'] is allowed to be: unread, read, or sent  
$wftype = $_GET['node'] == 'sent' ? 'sender' : 'recipient';  
$filter = $_GET['node'] == 'sent' ? '' : ' AND (`flags` & '.$message_flags[$_GET['node']].') != 0';  
//$filter = ($_GET['node'] == 'unread' || $_GET['node'] == 'read') ? ($_GET['node'] == 'read' ? ' AND (`flags` & '.$message_flags['read'].') != 0' : ' AND (`flags` & '.$message_flags['unread'].') != 0') : '';  
$result = $sql->query('SELECT `messageid`, `parent`, `senderid`, `sender`, `subject`, MAX(`sendtime`) AS `sendtime` FROM `memberpostbox` WHERE `'.$wftype.'id` = '.$_SESSION['client']['number'].$filter.' AND (`flags` & '.$message_flags[$wftype.'_deleted'].') = 0 GROUP BY `parent` ORDER BY `sendtime` DESC');  

我是否必须重组我的表格或完全改变我这样做的方式?或者,这可以用我现在的东西来完成吗?

附加信息
表结构

CREATE TABLE IF NOT EXISTS `memberpostbox` (  
  `messageid` bigint(20) unsigned NOT NULL auto_increment,  
  `parentid` int(10) unsigned default NULL,  
  `senderid` varchar(255) collate utf8_unicode_ci NOT NULL,  
  `sender` varchar(255) collate utf8_unicode_ci NOT NULL,  
  `recipientid` varchar(255) collate utf8_unicode_ci NOT NULL,  
  `recipient` varchar(255) collate utf8_unicode_ci NOT NULL,  
  `subject` varchar(255) collate utf8_unicode_ci default NULL,  
  `message` longtext collate utf8_unicode_ci NOT NULL,  
  `sendtime` int(10) unsigned NOT NULL,  
  `flags` tinyint(3) unsigned NOT NULL default '0',  
  PRIMARY KEY  (`messageid`),  
  KEY `groupid` (`parentid`),  
  FULLTEXT KEY `search` (`subject`,`message`)  
ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=22 ;  

【问题讨论】:

    标签: php mysql


    【解决方案1】:

    对于未读消息

    'SELECT .... FROM memberpostbox WHERE flag=1'
    

    用于阅读消息

    'SELECT .... FROM memberpostbox WHERE flag=2'
    

    只有标志确定消息是否被读取,所以这将是显示正确列表的唯一部分.....当然,您必须在其中添加其余代码。

    // read
    $result = $sql->query(
        'SELECT 
           `messageid`, 
           `parent`, 
           `senderid`,
           `sender`, 
           `subject`, 
           MAX(`sendtime`) AS `sendtime` 
        FROM `memberpostbox` 
        WHERE `recipientid` = '.$_SESSION['client']['number'].$filter.' 
        AND `flags` = 2
        AND '.$message_flags[$wftype.'_deleted'].' = 0
        GROUP BY `parent` 
        ORDER BY `sendtime` DESC'
      );       
    

    【讨论】:

    • 我的代码有点混乱。我最初是按照你的方式做的。但是,我为消息定义了两个以上的位标志。所有标志为:未读、已读、收件人已删除、发件人已删除。这些存储在flags db 字段中(最大值为 15)。如果消息接收者“删除”消息,则设置recipient_deleted,而如果消息发送者执行相同操作,则设置sender_deleted。我这样做是为了避免冲突。 EX)如果发件人要删除邮件,收件人应该仍然可以查看它,除非收件人也将其删除。
    • 如果你有一个特定值的列表,那么你应该考虑标志的枚举数据类型,你仍然可以使用当前变量来设置标志。我也认为您还应该考虑为您想要做的每种不同类型的工作使用函数,例如:一个用于 delete() 用于 mark_as_read() 等等
    最近更新 更多