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

Grab the correct set of data from database Mysql/MariaDB

考虑来自 table

的以下数据

SELECT * 来自消息;

+----+------------+------------+----------------------------------------------------------------+------------+
| 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为登录用户

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

问题

当前查询将return

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

如果你是 运行 MySQL 8.0,你可以使用 window 函数来做到这一点:

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

重要的是按最小和最大对等点进行分区,这样可以避免将同一会话的消息放在同一组中,无论发送或接收者是谁。

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

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
    )