mysql sql查询如何实现发私信用户和其他用户的列表?要求消重所有重复的用户结果
私信表结构如下:
建表语句和数据
CREATE TABLE `message` ( `id` int(5) NOT NULL, `sender_id` int(5) DEFAULT NULL, `receivce_id` int(5) DEFAULT NULL, `content` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=gb2312; /*Data for the table `message` */ insert into `message`(`id`,`sender_id`,`receivce_id`,`content`) values (1,1,2,'1发给2'),(2,2,1,'2发给1'),(3,3,1,'3发给1'),(4,2,1,'2发给1'),(5,1,2,'1发给2'),(6,4,1,'4发给1'),(7,1,2,'1-2'),(8,2,1,'2-1'),(9,2,1,'2-1'),(10,1,2,'1-2'),(11,3,1,'3-1'),(12,3,2,'3-2'),(13,3,1,'3-1'),(14,4,1,'4-1'),(15,5,1,'5-1'),(16,1,5,'1-5'),(17,1,5,'1-5'),(18,1,6,'1-6'),(19,6,1,'6-1'),(20,1,7,'1-7'),(21,1,8,'1-8'),(22,1,9,NULL),(23,1,10,NULL),(24,11,1,NULL),(25,12,1,'12-1'),(26,13,1,'13-1'),(27,1,14,NULL),(28,15,1,'15-1');
要求得到1和所有用户的私信列表。
结果集如下:
id sender_id receivce_id content
1 1 2 1发给2
3 3 1 3发给1
6 4 1 4发给1
SELECT * FROM (
SELECT id, receivce_id,content,
CASE WHEN sender_id=1
THEN "发送方"
ELSE "接收方" END flag
FROM message WHERE sender_id=1
UNION
SELECT id,sender_id,content,
CASE WHEN sender_id=1
THEN "发送方"
ELSE "接收方" END flag
FROM message WHERE receivce_id=1
ORDER BY receivce_id DESC,id DESC )ta
GROUP BY receivce_id
ORDER BY id DESC
思路:
1.通过 UNION 语句 合并 receivce_id 和sender_id
2.根据 receivce_id 和 id 进行降序排序(为后续分组时,保留重复记录中 id最高的)
3.根据 receivce_id 分组 去重
4.根据id降序排序
SELECT d.* FROM (SELECT id, sender_id sid, receivce_id rId, content FROM message WHERE sender_id = 1 OR receivce_id = 1 GROUP BY sender_id, receivce_id) d WHERE d.id NOT IN (SELECT a.id FROM(SELECT id, sender_id sid, receivce_id rId FROM message WHERE sender_id = 1 OR receivce_id = 1 GROUP BY sender_id, receivce_id) AS a CROSS JOIN (SELECT id, receivce_id sid, sender_id rId FROM message WHERE sender_id = 1 OR receivce_id = 1 GROUP BY sender_id, receivce_id) AS b ON a.sid = b.sid AND a.rid = b.rid AND a.sid <> 1 );
这个行不行,写的有点麻烦。
思路是这样:
1 拿出所有与发送者ID为1交互的记录。
2 然后要去除两者互发的重复, 方法是独立出来思路1的记录, 将发送者和接受者位置交换,然后去两者的交集,那么交集就是两者互发的记录去除重复 假如1给2发了5条 2给1发了3条 在思路1 已经过滤成两条了 那么不管怎么取,取出来都应该只有两条 就是1 to 2 或者 2 to 1, 那么接下来就需要把这两条去除 就取接受ID不等于1就好了 因为发送ID已经为1了 那么就去出来了重复的ID。
3 在最外层取数据的时候把重复ID NOT IN一下就行了。
这是我的思路 , 不知道对不对。
先这么实现了:
1.先查到所有发私信的用户的并集
SELECT receiver_id FROM message where sender_id=1 UNION (SELECT sender_id FROM message where receiver_id=1)
2.循环该用户列表获取到最新的那条私信数据,标示是接收者还是发送者。
伪码
for receiver_id in receiver_ids{ var id="select id from message where sender_id="+receiver_id+" order by id desc"; if find get id &发送方 else id="select id from message where receiver_id="+receiver_id+" order by id desc"; get id &接收方 }
这样有个问题是排序可能不是最新发私信的用户在最上面,优势是逻辑相比清晰,而且可以查询java层的cache加快速度。
大家有更好的解决方案请提供下吧。
- 等 最代码怎么获取牛币啊?
- 完 谁来告诉我最代码上线的时间,答对者给5牛币,先来先得
- 等 牛友们,大家好,你们做程序员多久了?现在还好吗?
- 完 在微信打开的页面里进行app下载
- 等 最代码2014年欢乐聚声会
- 完 mysql如何查询表数据并且对3个字段降序的SQL?
- 完 最代码牛币机制改革
- 完 成功的在bae上使用了自定义运行环境 jetty+nginx的组合,大家对jetty+nginx优化有哪些心得?
- 完 进来分享一下各位牛牛是如何加入最代码大家庭的?
- 等 为什么java BufferedImage类处理大图直接抛出内存溢出的异常?
- 等 最代码是否开发手机app客户端?
- 完 java程序员学习哪些java的技术?java有哪些框架?都能做哪方面的开发?
- 等 php格式网页文件怎么运行?
- 等 Java volatile值获取的问题
- 等 前端vue,拦截了登录后台后,返回的token,requests拦截token,但是发送请求的时候,就出现跨越异常
- 等 大专本科计算机科班怎么找到Java工作?
- 等 eclipse怎么把三个java swing游戏项目合成一个项目?
- 完 伙伴们,大家都有什么好的解压方式么,分享一下~
- 完 三四线城市,6、7k,运维工作,索然无味,想去辞职上培训,各位牛牛有什么建议嘛
- 等 jsp页面输入中文变成问号
- 等 JPA在线上运行一段时间后报错Caused by: java.lang.IncompatibleClassChangeError: null
- 等 PHP 这个规则用preg_match_all怎么写
- 等 大佬们,有没有知道Alfresco如何配置LDAP登录呢?
- 等 php的install目录是框架带的吗?
- 等 Mac系统安装mysql成功,但是终端登录mysql为什么报Access denied for user root@localhost?
- 完 Mysql中能否使用select 1 from table查询?
- 等 mysql 分组查每组里创建时间最大的那条数据
- 完 MySql数据库中的主键和Oracle数据库中的如何通过sql确认那个字段是主键?
- 等 mysql如何实现查询一段时间的签到和未签到的用户信息按天展示?
- 等 mysql触发器为什么没执行?
- 等 mysql数据库查询问题
- 完 mysql主从配置:slave_IO_Running: No 怎么解决?
- 完 mysql自定义函数哪里出问题了
- 完 为什么本地WEB项目无法访问服务器Mysql数据库?
- 等 MySQL怎么查询每天打卡的最早时间和最晚时间?
- 完 linux如何查看mysql进程下某个线程执行的语句是什么?