gpt4 book ai didi

mysql - 使用 MySQL 从表中获取唯一数据

转载 作者:行者123 更新时间:2023-11-29 05:05:11 25 4
gpt4 key购买 nike

我的目标是获取用户 A 与其其他 friend 的所有最后消息。

我有 table 友和留言

friend 表如下

+---------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-----------------+------+-----+---------+----------------+
| id | int(6) unsigned | NO | PRI | NULL | auto_increment |
| user1 | int(6) unsigned | NO | MUL | NULL | |
| user2 | int(6) unsigned | NO | MUL | NULL | |
| pending | tinyint(1) | NO | | NULL | |
+---------+-----------------+------+-----+---------+----------------+

消息表如下

+-----------------+-----------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+-----------------+------+-----+-------------------+-----------------------------+
| id | int(6) unsigned | NO | PRI | NULL | auto_increment |
| sender | int(6) unsigned | NO | MUL | NULL | |
| receiver | int(6) unsigned | NO | MUL | NULL | |
| message | varchar(255) | NO | | NULL | |
| message_read | tinyint(1) | NO | | NULL | |
| message_visible | int(6) | YES | | NULL | |
| message_date | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-----------------+-----------------+------+-----+-------------------+-----------------------------+

这是个人资料表

+----------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-----------------+------+-----+---------+----------------+
| id | int(6) unsigned | NO | PRI | NULL | auto_increment |
| user_id | int(6) unsigned | NO | MUL | NULL | |
| nickname | varchar(50) | YES | UNI | NULL | |
| email | varchar(50) | YES | | NULL | |
| image | mediumblob | YES | | NULL | |
+----------+-----------------+------+-----+---------+----------------+

根据要求,这里是消息的数据集

+----+--------+----------+-------------------------------------------------------------+--------------+-----------------+---------------------+
| id | sender | receiver | message | message_read | message_visible | message_date |
+----+--------+----------+-------------------------------------------------------------+--------------+-----------------+---------------------+
| 1 | 1 | 2 | test | 1 | NULL | 2017-09-30 21:10:15 |
| 2 | 1 | 2 | test | 1 | NULL | 2017-09-30 21:10:16 |
| 3 | 2 | 1 | test | 1 | NULL | 2017-09-29 21:10:15 |
| 4 | 2 | 1 | test | 1 | NULL | 2017-09-30 21:10:14 |
| 5 | 1 | 4 | test | 1 | NULL | 2017-09-30 21:10:14 |
| 6 | 1 | 4 | test | 1 | NULL | 2017-09-30 21:10:15 |
| 7 | 4 | 1 | test | 1 | NULL | 2017-09-29 21:10:15 |
| 8 | 4 | 1 | test | 1 | NULL | 2017-09-30 21:10:17 |
| 9 | 5 | 1 | test | 1 | NULL | 2017-09-30 21:10:18 |
| 10 | 5 | 1 | test | 1 | NULL | 2017-09-30 21:10:15 |
| 11 | 1 | 5 | test | 1 | NULL | 2017-09-30 21:10:14 |
| 12 | 1 | 5 | test | 1 | NULL | 2017-09-30 21:10:15 |
| 13 | 1 | 7 | test | 1 | 7 | 2017-09-30 21:10:15 |
| 14 | 2 | 3 | test | 1 | NULL | 2017-09-30 21:10:15 |
| 15 | 2 | 3 | test | 1 | NULL | 2017-09-30 21:10:14 |
| 16 | 3 | 2 | test | 1 | NULL | 2017-09-30 21:10:17 |
| 17 | 3 | 2 | test | 1 | NULL | 2017-09-30 21:10:15 |
| 18 | 3 | 4 | test | 1 | NULL | 2017-09-30 21:10:15 |
| 19 | 3 | 4 | test | 1 | NULL | 2017-09-30 21:10:14 |
| 20 | 4 | 3 | test | 1 | NULL | 2017-09-30 21:10:17 |
| 21 | 4 | 3 | test | 1 | NULL | 2017-09-30 21:10:15 |
| 22 | 2 | 4 | test | 1 | NULL | 2017-09-30 21:10:15 |
| 23 | 2 | 4 | test | 1 | NULL | 2017-09-30 21:10:14 |
| 24 | 4 | 2 | test | 1 | NULL | 2017-09-30 21:10:17 |
| 25 | 4 | 2 | test | 1 | NULL | 2017-09-30 21:10:15 |
| 26 | 11 | 4 | test1 | 1 | NULL | 2017-10-19 13:24:53 |
| 27 | 11 | 6 | test2 | 1 | NULL | 2017-10-19 19:56:46 |
| 28 | 11 | 7 | test3 | 1 | NULL | 2017-10-19 12:30:38 |
| 29 | 4 | 11 | test1_response | 1 | NULL | 2017-10-19 21:03:27 |
| 30 | 6 | 11 | test2_response | 1 | NULL | 2017-10-19 21:03:34 |
| 31 | 13 | 6 | test1 | 1 | NULL | 2017-10-20 09:36:09 |
| 32 | 13 | 7 | test1 | 1 | NULL | 2017-10-20 09:36:13 |
| 33 | 11 | 13 | test11 | 1 | NULL | 2017-10-20 09:36:21 |
| 34 | 13 | 11 | test11_response | 1 | NULL | 2017-10-20 09:41:27 |
| 35 | 1013 | 2 | test | 1 | NULL | 2018-03-29 13:35:31 |
| 36 | 2 | 1013 | Longer text message test, and I wish this works beautifully | 1 | NULL | 2018-03-29 15:12:33 |
| 37 | 1013 | 2 | Longer text message test, and I wish this works beautifully | 1 | NULL | 2018-03-29 15:17:40 |
| 38 | 1013 | 2 | Longer text message test, and I wish this works beautifully | 1 | NULL | 2018-03-29 15:41:55 |
| 39 | 1015 | 2 | What's up | 1 | NULL | 2018-04-17 16:33:29 |
| 40 | 2 | 1015 | What up? | 1 | NULL | 2018-04-17 16:33:29 |
| 42 | 2 | 1015 | What's up | 0 | NULL | 2018-04-17 16:33:29 |
+----+--------+----------+-------------------------------------------------------------+--------------+-----------------+---------------------+

下面是 friend 的数据集

+-----+-------+-------+---------+
| id | user1 | user2 | pending |
+-----+-------+-------+---------+
| 1 | 1 | 2 | 0 |
| 3 | 1 | 5 | 0 |
| 4 | 6 | 1 | 0 |
| 6 | 2 | 5 | 0 |
| 7 | 3 | 5 | 0 |
| 8 | 6 | 2 | 0 |
| 9 | 6 | 1 | 0 |
| 10 | 5 | 4 | 0 |
| 11 | 4 | 1 | 0 |
| 12 | 1 | 7 | 1 |
| 19 | 12 | 1 | 1 |
| 20 | 12 | 2 | 0 |
| 22 | 12 | 4 | 0 |
| 23 | 12 | 11 | 0 |
| 25 | 6 | 11 | 0 |
| 26 | 7 | 11 | 0 |
| 27 | 7 | 12 | 0 |
| 28 | 6 | 13 | 0 |
| 29 | 7 | 13 | 0 |
| 30 | 11 | 13 | 0 |
| 31 | 1013 | 2 | 0 |
| 39 | 1015 | 2 | 0 |
| 104 | 1015 | 1021 | 1 |
+-----+-------+-------+---------+

下面是个人资料数据片段

+------+---------+----------+-------+-------+
| id | user_id | nickname | email | image |
+------+---------+----------+-------+-------+
| 1 | 1 | user1 | | NULL |
| 2 | 2 | user2 | NULL | NULL |
| 3 | 3 | user3 | NULL | NULL |
| 4 | 4 | user4 | NULL | NULL |
| 1014 | 1018 | user1019 | NULL | NULL |
| 1015 | 1019 | user1020 | NULL | NULL |
| 1016 | 1020 | user1021 | NULL | NULL |
| 1017 | 1021 | user1022 | NULL | NULL |
+------+---------+----------+-------+-------+

我根据 StackOverFlow 上发布的一些很棒的答案编写了我的声明

这是我的sql语句:

SELECT msg.message, msg.message_read, msg.message_date,   
CASE WHEN msg.receiver = 1013
THEN (SELECT nickname FROM profile WHERE user_id = msg.sender)
ELSE (SELECT nickname FROM profile WHERE user_id = msg.receiver)
END AS name,

CASE WHEN msg.receiver = 1013
THEN (SELECT image FROM profile WHERE user_id = msg.sender)
ELSE (SELECT image FROM profile WHERE user_id = msg.receiver)
END AS image

FROM message msg
JOIN
(SELECT user, max(message_date) m
FROM
((SELECT id, receiver user, message_date FROM message WHERE sender = 1015 AND (message_visible =1 OR message_visible IS NULL))
UNION
(SELECT id, sender user, message_date FROM message WHERE receiver = 1015 AND (message_visible =1 OR message_visible IS NULL))) m1 GROUP BY user) m2 ON
((sender = 1015 AND receiver = user) OR (sender = user AND receiver = 1015)) AND (message_date = m) ORDER BY message_date desc;

我得到的结果是

+-----------+--------------+---------------------+----------+-------+
| message | message_read | message_date | name | image |
+-----------+--------------+---------------------+----------+-------+
| What's up | 1 | 2018-04-17 16:33:29 | user2 | NULL |
| What up? | 1 | 2018-04-17 16:33:29 | user1016 | NULL |
| What's up | 0 | 2018-04-17 16:33:29 | user1016 | NULL |
+-----------+--------------+---------------------+----------+-------+

我只想得到其中一个。哪个并不重要。当然,如果有更多的用户,就会有更多的消息。问题是当我有相同的 message_date 时。虽然同时发送消息似乎不太可信,但我至少想学习如何控制这种情况。

最佳答案

首先,您从您的用户 A 那里获得与其他任何人的消息。我没有包含消息何时不可见的条件,因为问题中的逻辑不明确。您必须自己添加。

SQL DEMO (没有配置文件表)

SELECT m.message, 
m.message_read,
m.message_date,
CASE WHEN m.sender = @userA_ID
THEN m.receiver
ELSE m.sender
END as friend_id,
CASE WHEN m.sender = @userA_ID
THEN p2.nickname
ELSE p1.nickname
END as name,
CASE WHEN m.sender = @userA_ID
THEN p2.image
ELSE p1.image
END as image
FROM message as m
JOIN profile as p1
ON m.sender = p1.user_id -- sender
JOIN profile as p2
ON m.receiver = p1.user_id -- receiver
WHERE @userA_ID IN (m.sender, m.receiver)

现在您使用变量按 friend 和日期对消息进行排序,请注意您使用 friend_id 以防两个 friend 同名。

SELECT t.*,
@rn := if(@friend = t.friend_id,
@rn + 1,
if( @friend := t.friend_id, 1, 1)
) as rn
FROM ( ** previous_query ** ) as t
CROSS JOIN ( SELECT @rn := 0, @friend := 0 ) as var
ORDER BY t.friend_id, t.message_date desc

请注意,您可以添加另一个条件来处理相同日期的关系

最后,您使用 rn = 1

过滤消息
SELECT *
FROM ( ** second query **) q
WHERE q.rn = 1

关于mysql - 使用 MySQL 从表中获取唯一数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49890897/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com