从数据库 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 中获取正确的数据集的主要内容,如果未能解决你的问题,请参考以下文章
无法从 information_schema (MySQL/MariaDB) 访问列名
哪种方法可以更快地使用 PHP/Laravel 从 MySQL/MariaDB 获取所有 POI