mysql - 从 MySQL 获取唯一数据

标签 mysql database select

我正在尝试获取最新消息列表。情况是这样的:当有完全相同时间发送的消息时,sequel 语句会选择所有消息。我只需要来自每个聊天室的一条消息,即最新消息。在@JuanCarlosOropeza(以及他出色的 fiddle http://sqlfiddle.com/#!9/d506e/10,我将立即将其包含在我就此主题提出的每个问题中)的帮助下,我得到了下面的续集声明。

SELECT *
FROM (  SELECT t.*,
               @rn := if(@friend = t.friend_id, 
                         @rn + 1,
                         if( @friend := t.friend_id, 1, 1)
                        ) as rn
        FROM ( 
                SELECT m.message, 
                       m.message_read,
                       m.message_date,
                       CASE WHEN m.sender = 4
                            THEN m.receiver
                            ELSE m.sender
                       END as friend_id,
                       CASE WHEN m.sender = 4
                            THEN p2.nickname
                            ELSE p1.nickname
                       END as name,
                       CASE WHEN m.sender = 4
                            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 = p2.user_id  -- receiver
                WHERE 4 IN (m.sender, m.receiver)
        ) as t
        CROSS JOIN ( SELECT @rn := 0, @friend := 0 ) as var
        ORDER BY t.friend_id, t.message_date desc
     ) q
WHERE q.rn = 1

上面的续集声明做得很好;然而,它有一个缺陷。 ORDER BY t.friend_id, t.message_date desc 不考虑“完全相同的 message_date”。同时发送消息很可能是不可能的,但谁知道呢?

好友表:

+----+-------+-------+---------+--------------+
ø id ø user1 ø user2 ø pending ø request_date ø
+----+-------+-------+---------+--------------+
ø  1 ø     4 ø     2 ø       0 ø 2018-05-09   ø
ø  2 ø     5 ø     2 ø       0 ø 2018-05-09   ø
ø  3 ø     1 ø     4 ø       0 ø 2018-05-09   ø
+----+-------+-------+---------+--------------+

配置文件表:

+----+---------+----------------------+---------------+-------+
ø id ø user_id ø nickname             ø email         ø image ø
+----+---------+----------------------+---------------+-------+
ø  1 ø       1 ø Welcome to MathMatch ø test@test.com ø NULL  ø
ø  2 ø       2 ø user3                ø NULL          ø NULL  ø
ø  3 ø       3 ø USER4                ø NULL          ø NULL  ø
ø  4 ø       4 ø elokiller            ø NULL          ø NULL  ø
ø  5 ø       5 ø USER6                ø NULL          ø NULL  ø
+----+---------+----------------------+---------------+-------+

消息表:

+----+--------+----------+-----------+--------------+-----------------+---------------------+
ø id ø sender ø receiver ø message   ø message_read ø message_visible ø message_date        ø
+----+--------+----------+-----------+--------------+-----------------+---------------------+
ø  1 ø      4 ø        2 ø lulz      ø            1 ø               2 ø 2018-05-15 10:24:36 ø
ø  2 ø      1 ø        4 ø Hey Buddy ø            1 ø            NULL ø 2018-05-10 11:58:39 ø
ø  3 ø      2 ø        4 ø nooo      ø            1 ø               2 ø 2018-05-15 10:24:36 ø
ø  4 ø      4 ø        2 ø shut up   ø            1 ø               2 ø 2018-05-15 10:24:36 ø
+----+--------+----------+-----------+--------------+-----------------+---------------------+

如果您知道如何解决此问题,那就太好了。当我运行上面的sequel语句时,此时得到的结果如下。

+-----------+--------------+---------------------+-----------+----------------------+-------+------+
ø message   ø message_read ø message_date        ø friend_id ø name                 ø image ø rn   ø
+-----------+--------------+---------------------+-----------+----------------------+-------+------+
ø Hey Buddy ø            1 ø 2018-05-10 11:58:39 ø         1 ø Welcome to MathMatch ø NULL  ø    1 ø
ø lulz      ø            1 ø 2018-05-15 10:24:36 ø         2 ø user3                ø NULL  ø    1 ø
ø nooo      ø            1 ø 2018-05-15 10:24:36 ø         2 ø user3                ø NULL  ø    1 ø
+-----------+--------------+---------------------+-----------+----------------------+-------+------+

我期望的结果:

+-----------+--------------+---------------------+-----------+----------------------+-------+------+
ø message   ø message_read ø message_date        ø friend_id ø name                 ø image ø rn   ø
+-----------+--------------+---------------------+-----------+----------------------+-------+------+
ø Hey Buddy ø            1 ø 2018-05-10 11:58:39 ø         1 ø Welcome to MathMatch ø NULL  ø    1 ø
ø lulz      ø            1 ø 2018-05-15 10:24:36 ø         2 ø user3                ø NULL  ø    1 ø
+-----------+--------------+---------------------+-----------+----------------------+-------+------+

如您所见,有两条消息来自同一个friend_id,即2。我只想检索该 friend 的一条消息。感谢您抽出宝贵时间。任何评论都会有帮助~

<小时/>

另一个值得关注的场景。

当前消息表:

+----+--------+----------+-----------+--------------+-----------------+---------------------+
| id | sender | receiver | message   | message_read | message_visible | message_date        |
+----+--------+----------+-----------+--------------+-----------------+---------------------+
|  1 |      4 |        2 | lulz      |            1 |               2 | 2018-05-15 10:24:36 |
|  2 |      1 |        4 | Hey Buddy |            1 |            NULL | 2018-05-10 11:58:39 |
|  3 |      2 |        4 | nooo      |            1 |               2 | 2018-05-15 10:24:36 |
|  4 |      4 |        2 | shut up   |            1 |               2 | 2018-05-15 10:24:36 |
|  5 |      4 |        2 | heha      |            1 |            NULL | 2018-05-15 10:36:11 |
|  6 |      1 |        4 | SUP MATE  |            1 |            NULL | 2018-05-15 11:04:24 |
+----+--------+----------+-----------+--------------+-----------------+---------------------+

当前结果表:

+-----------+--------------+---------------------+-----------+-------+-------+------+
| message   | message_read | message_date        | friend_id | name  | image | rn   |
+-----------+--------------+---------------------+-----------+-------+-------+------+
| Hey Buddy |            1 | 2018-05-10 11:58:39 |         1 | JUAN  | NULL  |    1 |
| nooo      |            1 | 2018-05-15 10:24:36 |         2 | user3 | NULL  |    1 |
+-----------+--------------+---------------------+-----------+-------+-------+------+

预期结果

+-----------+--------------+---------------------+-----------+-------+-------+------+
| message   | message_read | message_date        | friend_id | name  | image | rn   |
+-----------+--------------+---------------------+-----------+-------+-------+------+
| SUP MATE  |            1 | 2018-05-15 11:04:24 |         1 | JUAN  | NULL  |    1 |
| heha      |            1 | 2018-05-15 10:36:11 |         2 | user3 | NULL  |    1 |
+-----------+--------------+---------------------+-----------+-------+-------+------+

最佳答案

如果您将 ID 添加到结果表中,则可以通过friend_id 选择最新的 ID 和组。

假设您能够构建以下类型的 View

CREATE TABLE IF NOT EXISTS `MESSAGES` (
  `id` int(6) unsigned NOT NULL,
  `friend_id` int(3) unsigned NOT NULL,
  `message_time` varchar(200) NOT NULL,
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `MESSAGES` (`id`, `friend_id`, `message_time`) VALUES
  ('1', '1', '2018-05-10 11:58:39'),
  ('2', '2', '2018-05-15 10:24:36'),
  ('3', '2', '2018-05-15 10:24:36');

然后,您将首先选择按好友 ID 分组的最长时间消息,然后再选择其中 id 最长的消息。您可以使用以下 SQL 来实现。

SELECT MESSAGES.id, MESSAGES.friend_id, MESSAGES.message_time FROM

(
  SELECT max(id) as id, friend_id FROM
  (SELECT id,
          m.friend_id,
          m.message_time
   FROM MESSAGES m
   JOIN
     (SELECT friend_id,
             MAX(message_time) AS message_time
      FROM MESSAGES
      GROUP BY friend_id) mx ON mx.friend_id = m.friend_id
   AND mx.message_time = m.message_time) b GROUP BY friend_id
) a JOIN 
   MESSAGES on a.id = MESSAGES.id ;

获取上述查询中 MESSAGES 表所需的结果应该相当简单,因为您已经按照您的问题做了类似的操作。

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

相关文章:

sql - SQL 中现有字段名称后未放置逗号时会发生什么

sql - 如何从大表中选择行对?

php - Mysql查询,item包含所有指定的标签

database - Protractor是否也可以直接用于数据库测试?

java - 无法在我的 Android 应用程序中从 mysql 数据库获取数据到 ListView

sql - 用于通配符查找的正则表达式帮助

sql - 当第一个表中的行被删除时如何从第二个表中删除数据

uitableview - 如何最初在UITableView中选择一行

mysql - 非数字或字母 db 值的值范围查询

php - 试图理解 PHP 中的 PDO;不断收到空错误