mysql - 隐藏聊天中比不同表格中的时间戳更早的消息
问题描述
我有以下聊天系统的数据库结构:
请看下面的小提琴
conversations
+-----------------+
| COLUMN_NAME |
+-----------------+
| conversation_id |
| name |
| created_at |
| updated_at |
+-----------------+
conversation_participants
+-----------------+
| COLUMN_NAME |
+-----------------+
| id |
| user_id |
| conversation_id |
| deleted_at |
+-----------------+
messages
+-----------------+
| COLUMN_NAME |
+-----------------+
| message_id |
| user_id |
| conversation_id |
| message |
| created_at |
| updated_at |
+-----------------+
我还根据此建议获取最后 x 条消息https://softonsofa.com/tweaking-eloquent-relations-how-to-get-n-related-models-per-parent/
现在我只需要获取比时间戳更新的deleted_at
消息null
。
由于我使用 Laravel 预加载,因此我很难调整查询以使其在没有特定conversation_id
.
我需要在查询中包含最后 x 条消息。如果我只获取特定的对话,它也可以工作
SELECT
*
FROM
(
SELECT
`messages`.*,
@rank := IF(
@group = conversation_id,
@rank +1,
1
) AS rank_bae5f28cab9179ba9b470ec66ec93b7b,
@group := conversation_id AS group_bae5f28cab9179ba9b470ec66ec93b7b
FROM
(
SELECT
@rank := 0,
@group := 0
) AS vars,
messages,
(
SELECT
IFNULL(
deleted_at,
'0000-00-00 00:00:00'
) AS deleted_at
FROM
conversation_participants
WHERE
conversation_participants.conversation_id = 84 AND conversation_participants.user_id = 1
LIMIT 1
) AS deleted_at
WHERE
messages.created_at > deleted_at
ORDER BY
`conversation_id` ASC,
`created_at`
DESC
) AS messages
WHERE
`rank_bae5f28cab9179ba9b470ec66ec93b7b` <= 15 AND `messages`.`conversation_id` IN (84)
然后我尝试在此子查询中使用连接来包含“deleted_at”时间戳
SELECT
IFNULL(
deleted_at,
'0000-00-00 00:00:00'
) AS deleted_at
FROM
conversation_participants
JOIN
messages
ON
conversation_participants.conversation_id = messages.conversation_id
WHERE
conversation_participants.user_id = 1
LIMIT 1
但我总是收到价值'0000-00-00 00:00:00'
。deleted
deleted_at
那么如果值不是,我如何获取最新消息并过滤它们null
?
编辑:
澄清一下:我必须使用这个查询
SELECT
*
FROM
(
SELECT
`messages`.*,
@rank := IF(
@group = conversation_id,
@rank +1,
1
) AS rank_bae5f28cab9179ba9b470ec66ec93b7b,
@group := conversation_id AS group_bae5f28cab9179ba9b470ec66ec93b7b
FROM
(
SELECT
@rank := 0,
@group := 0
) AS vars,
messages
ORDER BY
`conversation_id` ASC,
`created_at`
DESC
) AS messages
WHERE
`rank_bae5f28cab9179ba9b470ec66ec93b7b` <= 15
所以 Laravel 只获取给定数量的消息,在这个例子中:15。
我知道我可以做一个循环,获取时间戳并以这种方式过滤它,但这会导致 n+2 查询问题。
我需要一种方法来为当前登录的用户应用连接,其中时间戳用于过滤最后的消息。
编辑2:
这是一个示例小提琴https://www.db-fiddle.com/f/3W2E99RYDPyebBYxcM1xyo/4
解决方案
推荐阅读
- c# - 如何在 C# WPF 中为一组图像设置正确的布局?
- python - 什么是 128 维向量分类的最佳选择。SVM 还是随机森林?
- node.js - 如何在云函数的 config.json 文件中提及 .csv 和 .json 文件格式来触发 DAG
- security - 在没有凭据的情况下保护 URL
- amazon-web-services - Amazon SQS - 重新排队和删除消息功能
- android - 错误:无法实例化接收器...没有零参数构造函数
- python - matplotlib 3.1.1 是否完全向后兼容 matplotlib 2.2.4?
- reactjs - 静态NextJS动态展示组件
- python - 以高优先级运行子进程
- performance - Magento2 可配置产品慢