我有以下MySQL表:
CREATE TABLE IF NOT EXISTS `conversations` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user1_id` int(11) NOT NULL,
`user2_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `user1_id_2` (`user1_id`,`user2_id`)
);
CREATE TABLE IF NOT EXISTS `messages` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`conversation_id` int(11) NOT NULL,
`sender_id` int(11) NOT NULL,
`recipient_id` int(11) NOT NULL,
`subject` varchar(64) NOT NULL,
`body` text NOT NULL,
`created` datetime DEFAULT NULL,
`is_deleted_by_sender` tinyint(3) unsigned NOT NULL DEFAULT '0',
`is_deleted_by_recipient` tinyint(3) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
);
注意:在会话表中,user1_id小于或等于user2_id。
我想获取用户X的会话列表,其中每个会话由该对话中用户X尚未删除的最后一条消息显示,并对结果进行分页。 (就像facebook消息一样。无论X或其他用户发送了最后一条消息,它都显示为显示消息。
我来到了group-wise maximum solution,它帮助我创建了以下子查询:
SELECT MAX(SubTable.id) AS id, conversation_id
FROM newtravel.messages AS SubTable
WHERE (
((SubTable.sender_id = 9) AND (SubTable.is_deleted_by_sender = 0))
OR
((SubTable.recipient_id = 9) AND (SubTable.is_deleted_by_recipient = 0))
)
GROUP BY conversation_id
我们可以在$ this-> Paginator->设置数组中将此子查询用作连接表吗?如果答案是肯定的,它应该生成如下查询:
SELECT m1.id, m1.conversation_id, m1.body, m1.sender_id, m1.recipient_id
FROM messages m1
INNER JOIN ( THE_SUB_QUERY_ABOVE ) m2
ON ( m1.conversation_id = m2.conversation_id
AND m1.id = m2.id )
ORDER BY m1.id DESC
此最终查询返回所需结果。但我无法找到在PaginatorComponent中设置正确选项的方法。官方文档不足以进行此类查询。那么,在这种情况下我们如何配置查找条件,联接,子查询等?
答案 0 :(得分:0)
好的。我已经解决了这个问题如下:
$this->Message->Behaviors->attach('Containable');
$conditionsSubQuery = array(
'OR' => array(
array(
'SubTable.sender_id' => $this->Auth->user('id'),
'SubTable.is_deleted_by_sender' => 0
),
array(
'SubTable.recipient_id' => $this->Auth->user('id'),
'SubTable.is_deleted_by_recipient' => 0
)
)
);
$db = $this->Message->getDataSource();
$subQuery = $db->buildStatement(
array(
'fields' => array('MAX(id)'),
'table' => $db->fullTableName($this->Message),
'alias' => 'SubTable',
'limit' => null,
'offset' => null,
'joins' => array(),
'conditions' => $conditionsSubQuery,
'order' => null,
'group' => 'conversation_id',
), $this->Message
);
$subQuery = ' Message.id IN (' . $subQuery . ') ';
$this->Paginator->settings = array(
'Message' => array(
'limit' => 5,
'maxLimit' => 5,
'contain' => array(
'Sender' => array(
'id', 'name', 'is_online', 'profile_image', 'thumbnail'
),
'Recipient' => array(
'id', 'name', 'is_online', 'profile_image', 'thumbnail'
),
'Conversation'
),
'order' => 'Message.id DESC'
)
);
$this->set('conversations', $this->Paginator->paginate('Message', $subQuery));
请注意,“消息”属于“发件人”和“收件人”,它们是“用户”表的别名。