问下我这个需求的sql咋样写

这是一个记录发送消息的表。我想要找出与a用户有过交流的不同用户最新消息(a发出和a接收)。比如拿a和b交流过的消息举例,就有第1行和第3、7、8行,a都有和b交流过(无论a是接收还是发送方),然后这4条消息只取date字段为最新的那一条,其余不要。剩余的比如a和c、a和e都有交流过等等,也是这样子查出来。

img

测试数据如下:

/*
 Navicat Premium Data Transfer

 Source Server         : 192.168.0.81_3306
 Source Server Type    : MySQL
 Source Server Version : 50739
 Source Host           : 192.168.0.81:3306
 Source Schema         : operations

 Target Server Type    : MySQL
 Target Server Version : 50739
 File Encoding         : 65001

 Date: 27/06/2023 17:52:32
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for test
-- ----------------------------
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test`  (
  `id` int(11) NOT NULL,
  `sender_id` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `receiver_id` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `content_type` int(11) NULL DEFAULT NULL,
  `content` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `date` datetime(0) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of test
-- ----------------------------
INSERT INTO `test` VALUES (1, 'b', 'a', NULL, NULL, '2023-06-13 17:49:09');
INSERT INTO `test` VALUES (2, 'a', 'd', NULL, NULL, '2023-05-31 17:49:14');
INSERT INTO `test` VALUES (3, 'a', 'b', NULL, NULL, '2023-06-08 17:49:19');
INSERT INTO `test` VALUES (4, 'd', 'a', NULL, NULL, '2023-06-09 17:49:22');
INSERT INTO `test` VALUES (5, 'a', 'c', NULL, NULL, '2023-06-17 17:49:26');
INSERT INTO `test` VALUES (6, 'e', 'c', NULL, NULL, '2023-06-10 17:49:29');
INSERT INTO `test` VALUES (7, 'a', 'b', NULL, NULL, '2023-06-18 17:49:33');
INSERT INTO `test` VALUES (8, 'b', 'a', NULL, NULL, '2023-06-01 17:49:36');
INSERT INTO `test` VALUES (9, 'e', 'a', NULL, NULL, '2023-06-02 17:49:39');
INSERT INTO `test` VALUES (10, 'c', 'b', NULL, NULL, '2023-06-03 17:49:43');

SET FOREIGN_KEY_CHECKS = 1;

查询语句如下:
按照需求只需要找到 发送方是a且接收方是b, 或 发送方是b且接收方是a 的数据 然后倒序排列时间 limit取1条就行。

select * from test 
where (sender_id='a' and receiver_id='b') 
or 
(sender_id='b' and receiver_id='a') 
order by `date` desc limit 1

要查跟a打过电话的所有人?那得借助函数。

select  *,concat(sender_id,receiver_id) as a from test  
where FIND_IN_SET('a',concat(sender_id,',',receiver_id)) order by `date` desc 
+----+-----------+-------------+--------------+---------+---------------------+----+
| id | sender_id | receiver_id | content_type | content | date                | a  |
+----+-----------+-------------+--------------+---------+---------------------+----+
|  7 | a         | b           |         NULL | NULL    | 2023-06-18 17:49:33 | ab |
|  5 | a         | c           |         NULL | NULL    | 2023-06-17 17:49:26 | ac |
|  1 | b         | a           |         NULL | NULL    | 2023-06-13 17:49:09 | ba |
|  4 | d         | a           |         NULL | NULL    | 2023-06-09 17:49:22 | da |
|  3 | a         | b           |         NULL | NULL    | 2023-06-08 17:49:19 | ab |
|  9 | e         | a           |         NULL | NULL    | 2023-06-02 17:49:39 | ea |
|  8 | b         | a           |         NULL | NULL    | 2023-06-01 17:49:36 | ba |
|  2 | a         | d           |         NULL | NULL    | 2023-05-31 17:49:14 | ad |
+----+-----------+-------------+--------------+---------+---------------------+----+

然后作为子表group by ..

select max(date),a from (
select  *,replace(concat(sender_id,receiver_id),'a','') as a 
from test  
where FIND_IN_SET('a',concat(sender_id,',',receiver_id)) 
order by `a` asc,`date` desc) _t GROUP BY _t.a

结果

+---------------------+---+
| max(date)           | a |
+---------------------+---+
| 2023-06-18 17:49:33 | b |
| 2023-06-17 17:49:26 | c |
| 2023-06-09 17:49:22 | d |
| 2023-06-02 17:49:39 | e |
+---------------------+---+

基于new bing部分指引作答:
要找出与用户 a 有过交流的不同用户的最新消息记录,您可以使用 SQL 查询语句来实现。假设您的表名为 "messages",包含列 "sender"(发送方)、"receiver"(接收方)和 "date"(日期)。

以下是一个示例查询语句:

SELECT *
FROM messages
WHERE (sender = 'a' OR receiver = 'a')
  AND date IN (
    SELECT MAX(date)
    FROM messages
    WHERE sender <> 'a' AND receiver <> 'a'
      AND (sender = 'a' OR receiver = 'a')
    GROUP BY CASE
      WHEN sender = 'a' THEN receiver
      ELSE sender
    END
  )

上述查询语句按照以下步骤进行筛选:

  1. 首先,通过 (sender = 'a' OR receiver = 'a') 条件选择所有与用户 a 有过交流的消息记录。
  2. 然后,在这些记录中,通过子查询 SELECT MAX(date) FROM messages WHERE sender <> 'a' AND receiver <> 'a' AND (sender = 'a' OR receiver = 'a') GROUP BY CASE WHEN sender = 'a' THEN receiver ELSE sender END 找到每个与用户 a 有过交流的不同用户的最新日期。
  3. 最后,在主查询中,使用 AND date IN (...) 条件将日期与最新日期匹配,以获取最新的消息记录。

请根据您的具体情况修改表名、列名和用户标识符。这个查询将返回与用户 a 有过交流的不同用户的最新消息记录。
你可以根据你的字段修改下sql

  • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/7584267
  • 除此之外, 这篇博客: 工作遇到的sql问题:A表a字段更新到B表b字段 & A表c字段根据a字段进行刷数中的 三:A表c字段根据a字段进行刷数 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • demo表count字段 要统计names有多少个名字
    在这里插入图片描述

    查询sql

    select *,IF
    	((
    			LENGTH( names )- LENGTH(
    			REPLACE ( names, ',', '' )) + 1 
    			) IS NULL,
    		0,(
    			LENGTH( names )- LENGTH(
    			REPLACE ( names, ',', '' )) + 1 
    		)
    	)  
    	from demo
    

    查询结果:
    在这里插入图片描述

    更新sql

    ## 统计每行数据有多少个名字
    update demo set count = IF
    	((
    			LENGTH( names )- LENGTH(
    			REPLACE ( names, ',', '' )) + 1 
    			) IS NULL,
    		0,(
    			LENGTH( names )- LENGTH(
    			REPLACE ( names, ',', '' )) + 1 
    		)
    	) ;
    

    更新结果
    在这里插入图片描述
    ps: 仅记录工作中遇到的sql问题,我是渣渣涛,我要努力学习。

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632