从数据库 Mysql/MariaDB 中获取正确的数据集

Posted

技术标签:

【中文标题】从数据库 Mysql/MariaDB 中获取正确的数据集【英文标题】:Grab the correct set of data from database Mysql/MariaDB 【发布时间】:2020-07-11 05:07:16 【问题描述】:

考虑以下表格中的数据

从消息中选择 *;

+----+------------+------------+----------------------------------------------------------------+------------+
| id | did_from   | did_to     | message                                                        | timestamp  |
+----+------------+------------+----------------------------------------------------------------+------------+
| 28 | 3369377501 | 3365024246 | Hey                                                            | 1585465342 |
| 29 | 3365024246 | 3369377501 | Whatcha doing?                                                 | 1585465349 |
| 30 | 3369377501 | 3365024246 | Driving, whatcha doing?                                        | 1585465369 |
| 31 | 3365024246 | 3369377501 | Driving and texting.                                           | 1585465375 |
| 32 | 3369377501 | 3365024246 | Hmmmm, are you sure you should be doing that?                  | 1585465395 |
| 39 | 3365024246 | 3369377501 | Yes because im a textpert                                      | 1585465500 |
| 40 | 3365024246 | 3369377501 | An expert at texting                                           | 1585465517 |
| 42 | 3365024246 | 3369377501 | Rejecting the notion that you think ill be wrecking            | 1585465550 |
| 43 | 3365024246 | 3369377501 | Due to the fact that im distracted?                            | 1585465559 |
| 44 | 3365024246 | 3369377501 | I multi-task best behind the wheel when i get textually active | 1585465577 |
| 50 | 3365024246 | 3369377501 | texting is cool                                                | 1585518726 |
| 51 | 3369377501 | 3365024246 | I agree                                                        | 1585518740 |
| 52 | 3365024246 | 3369377501 | Hey                                                            | 1585573071 |
| 53 | 3369377501 | 3365024246 | Hey                                                            | 1585573087 |
| 54 | 3365024246 | 3369377501 | whats up                                                       | 1585576304 |
+----+------------+------------+----------------------------------------------------------------+------------+

如果这是 2 个人之间的对话,并且我想在对话中获取其他人的最后一条消息,我会运行查询

SELECT * FROM messages WHERE (id IN ( SELECT MAX(id) FROM messages GROUP BY did_from ) AND did_to='3365024246') OR (id IN ( SELECT MAX(id) FROM messages GROUP BY did_from ) AND did_from='3365024246') ORDER BY id DESC

假设

DID: 3365024246 是登录的用户

我们不知道对话中的其他人是谁,我们正在搜索并获取对话列表并显示最后一条消息(以太由登录的人或其他人)

问题

当前查询将返回

+----+------------+------------+----------+------------+
| id | did_from   | did_to     | message  | timestamp  |
+----+------------+------------+----------+------------+
| 54 | 3365024246 | 3369377501 | whats up | 1585576304 |
| 53 | 3369377501 | 3365024246 | Hey      | 1585573087 |
+----+------------+------------+----------+------------+

预期结果

+----+------------+------------+----------+------------+
| id | did_from   | did_to     | message  | timestamp  |
+----+------------+------------+----------+------------+
| 54 | 365024246 | 3369377501 | whats up | 1585576304 |
+----+------------+------------+----------+------------+

【问题讨论】:

【参考方案1】:

如果您运行的是 mysql 8.0,您可以使用窗口函数来执行此操作:

select *
from (
    select 
        m.*, 
        row_number() over(
            partition by least(did_from, did_to), greatest(did_from, did_to)
            order by timestamp desc
        ) rn
    from messages m
    where 3365024246 in (did_from, did_to)
) t 
where rn = 1

重要的是按最小和最大的peer进行分区,这样可以避免将同一会话的消息放在同一个组中,而不管谁发送或接收。

在早期版本中,您可以使用相关子查询进行过滤:

select m.*
from messages m
where 
    3365024246 in (m1.did_from, m1.did_to) 
    and m.id = (
        select m1.id
        from messages m1
        where               
            and least(m1.did_from, m1.did_to) = least(m.did_from, m.did_to)
            and greatest(m1.did_from, m1.did_to) = greatest(m.did_from, m.did_to)
        order by m1.timestamp desc
        limit 1
    )

【讨论】:

这非常适合我们想要完成的工作,我希望我能对此表示赞同

以上是关于从数据库 Mysql/MariaDB 中获取正确的数据集的主要内容,如果未能解决你的问题,请参考以下文章

数据库MySQL/mariadb知识点——数据类型

无法从 information_schema (MySQL/MariaDB) 访问列名

哪种方法可以更快地使用 PHP/Laravel 从 MySQL/MariaDB 获取所有 POI

如何从 MySQL/MariaDB 中的二进制列格式化 uuid 字符串

Mysql(MariaDB)每次查询与从视图中读取?

游标内带有 INTO 的 MySQL/MariaDB 设置值的迭代不正确