简体   繁体   English

选择最后一个不同的对

[英]Select last distinct pair

Ok we have inbox table where we keep messages that users send to each other. 好的,我们有收件箱表,用于保存用户彼此发送的消息。 Here is the table: 表格如下:

CREATE TABLE IF NOT EXISTS `inbox` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`fromid` int(10) unsigned NOT NULL DEFAULT '0',
`toid` int(10) DEFAULT NULL,
`message` text CHARACTER SET utf8 NOT NULL,
`time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
KEY `toid` (`toid`),
KEY `fromid` (`fromid`),
KEY `fromid_2` (`fromid`,`toid`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1  ;

fromid and toid are id's of the users. fromid和toid是用户的ID。 We have their id's, times when the message is sent. 我们有他们的ID,即消息发送的时间。 What we need is a query that would return all messages that are not replied by 'our users' (admins). 我们需要一个查询,该查询将返回“我们的用户”(管理员)未答复的所有消息。 Table accounts keeps track of users. 表帐户跟踪用户。 To simplify: 为了简化:

CREATE TABLE IF NOT EXISTS `accounts` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`our` int(1) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1;

So basically, we need a query that gives us the users WHOSE messages WERE NOT ANSWERED by admins (our users), their count and the date of the last message they sent to ADMIN, ordered from last to oldest. 因此,基本上,我们需要一个查询,该查询为用户提供管理员(我们的用户)不应答的消息,其计数和发送给ADMIN的最后一条消息的日期(从最后到最早)。

So far we only have some basic queries, we didn't come up with anything reasonable that I could post. 到目前为止,我们只有一些基本查询,没有提出我可以发布的任何合理信息。

Thanks in advance. 提前致谢。

EDIT: From what I see we first need to find last interaction from two DISTINCT users in inbox table... then check & filter only those that were sent TO our users 编辑:从我所看到的,我们首先需要在收件箱表中查找来自两个DISTINCT用户的最后一次交互...然后检查并仅过滤发送给我们用户的那些

How about this? 这个怎么样?

SELECT i.* FROM inbox as i 
WHERE (i.toid, i.fromid) NOT IN 
(SELECT i2.fromid, i2.toid FROM inbox as i2 WHERE i2.`time` >= i1.`time` AND i2.id = 1);

Another way using join : 另一种使用join

SELECT DISTINCT i1.* 
FROM inbox as i1 LEFT JOIN inbox as i2 
    ON  i1.toid = 1 AND 
        i1.fromid = i2.toid AND 
        i1.toid = i2.fromid AND 
        i1.`time` <= i2.`time`
WHERE i2.id IS NULL;

Two possible solutions presented below: LEFT JOIN solution should perform better. 下面介绍了两种可能的解决方案: LEFT JOIN解决方案应该表现更好。

LEFT JOIN solution 左联接解决方案

SELECT 
 i.fromid, COUNT(*) AS unread, MAX(i.time) AS lastmsg 
FROM inbox AS i 
INNER JOIN accounts AS a 
 ON i.toid = a.id 
LEFT JOIN inbox AS i2 
 ON i.fromid = i2.toid AND i.toid = i2.fromid AND i.time <= i2.time 
WHERE a.our = 1 AND i2.id IS NULL
GROUP BY i.fromid
ORDER BY lastmsg DESC;

NOT IN solution 不在解决方案中

SELECT 
 i.fromid, COUNT(*) AS unread, MAX(i.time) AS lastmsg
FROM inbox AS i 
INNER JOIN accounts AS a ON i.toid = a.id 
WHERE a.our = 1 AND 
 (i.toid, i.fromid) 
 NOT IN (SELECT i2.fromid, i2.toid FROM inbox AS i2 WHERE i2.time >= i.time) 
GROUP BY i.fromid
ORDER BY lastmsg DESC;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM