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

时间:2018-04-18 03:51:15

标签: mysql sql

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

我有一位朋友和消息

朋友表如下

+---------+-----------------+------+-----+---------+----------------+
| 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 |
+----+--------+----------+-------------------------------------------------------------+--------------+-----------------+---------------------+

以下是朋友的数据集

+-----+-------+-------+---------+
| 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。虽然同时发送消息似乎难以置信,但我至少想学习如何控制这种情况。

1 个答案:

答案 0 :(得分:3)

首先,您与其他人一起从您的用户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_id以防两个朋友的姓名相同。

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