Группировка строк с одинаковым родительским идентификатором

#php #mysql

#php #mysql

Вопрос:

Я пишу скрипт для обмена личными сообщениями. Однако я столкнулся с несколькими проблемами на стороне 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 первого сообщения в потоке
subject: тема (или заголовок) потока
флаги: побитовые флаги (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` amp; '.$message_flags[$_GET['node']].') != 0';  
//$filter = ($_GET['node'] == 'unread' || $_GET['node'] == 'read') ? ($_GET['node'] == 'read' ? ' AND (`flags` amp; '.$message_flags['read'].') != 0' : ' AND (`flags` amp; '.$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` amp; '.$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 ;  
  

Ответ №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'
  );       
  

Комментарии:

1. Мой код немного сбивает с толку. Изначально я делал это по-вашему. Однако у меня определено более двух битовых флагов для сообщений. Все флаги: непрочитанный, прочитанный, получатель_удаленный, отправитель_удаленный. Они хранятся (с максимальным значением 15) в flags db-field. значение recipient_deleted устанавливается, если получатель сообщения «удаляет» сообщение, в то время как значение sender_deleted задается, если отправитель сообщения делает то же самое. Я делаю это таким образом, чтобы избежать конфликтов. ПРИМЕР) Если отправитель должен был удалить сообщение, получатель все равно должен был иметь возможность просмотреть его, если получатель не удалил его также.

2. если у вас есть список конкретных значений, вам следует рассмотреть тип данных enum для флагов, и вы все еще можете использовать текущие переменные для установки флагов. также я думаю, что вам также следует рассмотреть возможность использования функций для каждого ddifferent типа задания, которое вы хотите выполнить, например: для delete(), для mark_as_read () и так далее