PHP消息系统与mysql。一张表并查询新消息总数

标签 php mysql subquery

大家好,我的表消息和查询出现问题,我无法为对话中的每条第一条消息(conversation_id)选择全部新消息。这是我的表结构:

<小时/>

id、parent_id、sender_id、receiver_id、标题、正文、conversation_id、状态

这是我的 sql 查询:

SELECT * FROM messages AS m 

LEFT JOIN (
SELECT id as total_last_id, parent_id as total_parent_id, count(*) as total 
FROM messages WHERE recipient_id = 2 OR sender_id = 2 group by parent_id) as cm  
ON total_parent_id = m.id 

LEFT JOIN (
SELECT id as new_last_id, created as new_last_created, parent_id as new_parent_id, SUM(status) as new FROM messages 
WHERE recipient_id = 2 group by parent_id) as new 
ON new_parent_id = m.id WHERE m.recipient_id = 2 
GROUP BY m.conversation_id, m.parent_id HAVING (m.parent_id is null) ORDER BY m.created DESC

这是我的转储:

DROP TABLE IF EXISTS `messages`;
CREATE TABLE IF NOT EXISTS `messages` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `parent_id` int(11) DEFAULT NULL,
  `lft` int(11) DEFAULT NULL,
  `rght` int(11) DEFAULT NULL,
  `sender_id` varchar(36) NOT NULL,
  `recipient_id` varchar(36) NOT NULL,
  `title` varchar(1024) NOT NULL,
  `body` text,
  `readers` text COMMENT 'a serialized list of user ids that have read this message',
  `status` tinyint(1) NOT NULL DEFAULT '1',
  `is_archived` tinyint(1) NOT NULL DEFAULT '0',
  `creator_id` int(11) NOT NULL,
  `modifier_id` int(11) NOT NULL,
  `conversation_id` int(11) NOT NULL DEFAULT '0',
  `created` datetime DEFAULT NULL,
  `modified` datetime DEFAULT NULL,
  `deleted` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `all___` (`parent_id`,`lft`,`rght`,`sender_id`,`recipient_id`,`creator_id`,`modifier_id`,`conversation_id`,`status`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

示例数据:

INSERT INTO `messages` (`id`, `parent_id`, `lft`, `rght`, `sender_id`, `recipient_id`, `title`, `body`, `readers`, `status`, `is_archived`, `creator_id`, `modifier_id`, `conversation_id`, `created`, `modified`, `deleted`) VALUES
(291, 274, 36, 37, '41', '51', 'child 274', NULL, NULL, 0, 0, 41, 0, 2, '2013-10-31 06:05:23', '2013-10-31 06:05:23', NULL),
(290, 270, 18, 19, '41', '51', 'Parent id 270 ', NULL, NULL, 0, 0, 41, 0, 1, '2013-10-31 06:04:09', '2013-10-31 06:04:09', NULL),
(287, 283, 51, 52, '41', '51', 'test', NULL, NULL, 0, 0, 41, 0, 3, '2013-10-31 05:46:54', '2013-10-31 05:46:54', NULL),
(288, 280, 54, 55, '41', '51', 'test', NULL, NULL, 0, 0, 41, 0, 3, '2013-10-31 05:49:55', '2013-10-31 05:49:55', NULL),
(289, 273, 13, 14, '41', '51', 'c of 273', NULL, NULL, 0, 0, 41, 0, 1, '2013-10-31 05:59:56', '2013-10-31 05:59:56', NULL),
(286, 283, 49, 50, '41', '51', 'test', NULL, NULL, 0, 0, 41, 0, 3, '2013-10-31 05:46:33', '2013-10-31 05:46:33', NULL),
(283, 280, 46, 53, '41', '51', 'test', NULL, NULL, 0, 0, 41, 0, 3, '2013-10-31 05:32:38', '2013-10-31 05:32:38', NULL),
(284, 283, 47, 48, '51', '41', 'test', NULL, NULL, 1, 0, 51, 0, 3, '2013-10-31 05:33:33', '2013-10-31 05:33:33', NULL),
(285, 270, 16, 17, '41', '51', 'parent id 270', NULL, NULL, 0, 0, 41, 0, 1, '2013-10-31 05:33:57', '2013-10-31 05:33:57', NULL),
(282, 280, 44, 45, '51', '41', 'test', NULL, NULL, 1, 0, 51, 0, 3, '2013-10-31 05:30:41', '2013-10-31 05:30:41', NULL),
(281, 280, 42, 43, '51', '41', 'test', NULL, NULL, 1, 0, 51, 0, 3, '2013-10-31 05:27:59', '2013-10-31 05:27:59', NULL),
(280, NULL, 41, 56, '41', '51', 'Fourth', NULL, NULL, 0, 0, 41, 0, 3, '2013-10-31 04:28:18', '2013-10-31 04:28:18', NULL),
(279, 273, 11, 12, '51', '41', 'of 273', NULL, NULL, 1, 0, 51, 0, 1, '2013-10-31 04:26:30', '2013-10-31 04:26:30', NULL),
(277, 274, 32, 33, '51', '41', '0', NULL, NULL, 1, 0, 51, 0, 2, '2013-10-31 04:12:07', '2013-10-31 04:12:07', NULL),
(278, 274, 34, 35, '41', '51', 'test', NULL, NULL, 0, 0, 41, 0, 2, '2013-10-31 04:12:55', '2013-10-31 04:12:55', NULL),
(273, 270, 10, 15, '41', '51', 'Parent', NULL, NULL, 0, 0, 41, 0, 1, '2013-10-31 02:54:23', '2013-10-31 02:54:23', NULL),
(274, NULL, 27, 40, '41', '51', 'Third', NULL, NULL, 0, 0, 41, 0, 2, '2013-10-31 03:07:02', '2013-10-31 03:07:02', NULL),
(272, 270, 6, 9, '51', '41', 'Second Second', NULL, NULL, 1, 0, 51, 0, 1, '2013-10-31 02:52:55', '2013-10-31 02:52:55', NULL),
(270, NULL, 1, 26, '41', '51', 'Second message', NULL, NULL, 0, 0, 41, 0, 1, '2013-10-31 00:05:16', '2013-10-31 00:05:16', NULL),
(271, 270, 2, 5, '51', '41', 'Answer 1', NULL, NULL, 0, 0, 51, 0, 1, '2013-10-31 00:06:21', '2013-10-31 00:06:21', NULL),
(292, 274, 38, 39, '41', '51', 'test', NULL, NULL, 1, 0, 41, 0, 2, '2013-10-31 06:11:35', '2013-10-31 06:11:35', NULL),
(295, 272, 7, 8, '41', '51', 'child of 272', NULL, NULL, 1, 0, 41, 0, 1, '2013-10-31 07:04:06', '2013-10-31 07:04:06', NULL),
(294, 270, 20, 21, '41', '51', 'parent 270, child second', NULL, NULL, 1, 0, 41, 0, 1, '2013-10-31 06:12:17', '2013-10-31 06:12:17', NULL),
(296, 270, 22, 23, '41', '51', 'child of 270', NULL, NULL, 1, 0, 41, 0, 1, '2013-10-31 07:05:30', '2013-10-31 07:05:30', NULL),
(297, 270, 24, 25, '41', '51', 'child of 270', NULL, NULL, 1, 0, 41, 0, 1, '2013-10-31 07:06:11', '2013-10-31 07:06:11', NULL),
(298, NULL, 57, 70, '41', '51', 'First message', NULL, NULL, 0, 0, 41, 0, 4, '2013-10-31 07:43:49', '2013-10-31 07:43:49', NULL),
(299, 298, 58, 59, '51', '41', 'test', NULL, NULL, 1, 0, 51, 0, 4, '2013-10-31 07:45:54', '2013-10-31 07:45:54', NULL),
(300, 298, 60, 67, '41', '51', 'test', NULL, NULL, 0, 0, 41, 0, 4, '2013-10-31 07:46:21', '2013-10-31 07:46:21', NULL),
(301, 300, 61, 62, '51', '41', 'test', NULL, NULL, 1, 0, 51, 0, 4, '2013-10-31 07:46:38', '2013-10-31 07:46:38', NULL),
(302, 300, 63, 64, '41', '51', 'test', NULL, NULL, 0, 0, 41, 0, 4, '2013-10-31 07:47:08', '2013-10-31 07:47:08', NULL),
(303, 298, 68, 69, '41', '51', 'test', NULL, NULL, 0, 0, 41, 0, 4, '2013-10-31 07:54:45', '2013-10-31 07:54:45', NULL),
(304, 300, 65, 66, '41', '51', 'test', NULL, NULL, 0, 0, 41, 0, 4, '2013-10-31 07:54:58', '2013-10-31 07:54:58', NULL);

主要问题是它选择了错误的新消息总数...... 当我用户查询时,它会计算错误的新消息(当执行查询时,对话中的每个第一行(parent_id = null)行新计数错误)... 我该如何解决这个问题,或者我需要编辑带有表消息、对话、用户的消息传递插件的结构? 我认为一个 sql 查询可以与一张表一起工作......

最佳答案

    SELECT * FROM messages AS m 

    LEFT JOIN (SELECT id AS total_last_id, parent_id AS total_parent_id, COUNT(*) AS total 
    FROM messages WHERE recipient_id = 51 OR sender_id = 51 GROUP BY parent_id) AS cm  
    ON total_parent_id = m.id 

    LEFT JOIN (
    SELECT id AS new_last_id, created AS new_last_created, parent_id AS new_parent_id, SUM(STATUS) AS NEW FROM messages 
    GROUP BY parent_id) AS NEW 
    ON new_parent_id = m.id WHERE m.recipient_id = 51 
    GROUP BY m.conversation_id, m.parent_id HAVING (m.parent_id IS NULL) ORDER BY m.created DESC;

删除了第二个左连接中的 where 子句,因为您按照parent_id 和conversation_id 对它们进行计数。

关于PHP消息系统与mysql。一张表并查询新消息总数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19698850/

相关文章:

php - jquery 自动完成和 mySql 的问题

php - 将 Firebase Cloud Messaging 发送到手机设备

PHP 显示来自 MySQL 的图像 BLOB

MySql和subselect,为什么这么慢?

mysql - 内部联接中的临时表与子查询

php - 简单的 strtolower 不起作用

php - 如何使 laravel 护照中用户的所有 token 无效?

php - 无法在使用 php 脚本加密的 mysql 中解密

php - 计算 mysql 表中的列数不起作用

mysql - JOINS 而不是子选择