我有以下表格:
用户表
id(uuid) |
---|
someuuid |
someuuid |
广告表
id | owner_id(用户的 fkey) |
---|---|
someuuid | someuuid |
someuuid | someuuid |
留言表
id | 广告 | 发件人(fkey 用户) | 接收者(fkey用户) | 内容 | 创建于 | read_at(null表示未见) |
---|---|---|---|---|---|---|
someuuid | someuuid | someuuid | 一些文字 | 某天 | 某天 |
这意味着每条消息都与广告相关,发送者或接收者是广告的所有者。
现在我想查询每个用户(为了在收件箱中显示)他们所属的每个对话、最后一条消息的内容、该对话中创建最后一条消息的日期以及用户拥有的消息量尚未阅读该对话。
所以继续来说,2 个用户之间的每次对话都与消息的发送者或接收者发布的广告有关
我得到的最远的是能够使用以下查询检索每个对话、该对话中的最后一条消息以及最后一条消息的创建日期
SELECT *
FROM messages
, (
SELECT MAX(created_at) AS last_message_sent_at
FROM messages
WHERE (
messages.sender = '80d1c6070a7d' -- ID to compare with (logged in users's ID)
OR messages.receiver = '80d1c6070a7d' -- ID to compare with (logged in users's ID)
)
GROUP BY ad
) AS conversations
WHERE created_at = conversations.last_message_sent_at
ORDER BY messages.created_at DESC LIMIT 100 OFFSET 0
为了提供可能发生的情况的示例,请重新考虑问题中给出的详细信息。下面是一些假设的示例数据,可以模拟您的问题以及解决该问题的潜在查询。然而,当我们不知道您的数据实际上是什么样时,很容易犯错误,因此,在考虑许多注意事项的情况下,请考虑下面的示例。 (注意,我使用 varchar(20) 来避免尝试模拟 UUID 时出现问题):
DDL(这样我们就知道我们在处理什么)
CREATE TABLE users (
id varchar(20) PRIMARY KEY,
name VARCHAR(100)
);
CREATE TABLE ads (
id varchar(20) PRIMARY KEY,
owner_id varchar(20) REFERENCES users(id)
);
CREATE TABLE messages (
id varchar(20) ,
ad varchar(20) REFERENCES ads(id),
sender varchar(20) REFERENCES users(id),
receiver varchar(20) REFERENCES users(id),
content TEXT,
created_at TIMESTAMP,
read_at TIMESTAMP
);
样本数据(假设)
INSERT INTO users (id, name) VALUES
('80d1c6070a7d', 'User1'),
('someuuid2', 'User2'),
('someuuid3', 'User3');
INSERT INTO ads (id, owner_id) VALUES
('ad1', '80d1c6070a7d'),
('ad2', 'someuuid2'),
('ad3', 'someuuid3');
INSERT INTO messages (id, ad, sender, receiver, content, created_at, read_at) VALUES
('msg1', 'ad1', '80d1c6070a7d', 'someuuid3', 'Hello', '2023-11-27 10:00:00', '2023-11-27 10:05:00'),
('msg2', 'ad1', 'someuuid2', '80d1c6070a7d', 'Hi', '2023-11-27 10:02:00', NULL),
('msg3', 'ad2', 'someuuid3', '80d1c6070a7d', 'How are you?', '2023-11-27 11:00:00', NULL),
('msg4', 'ad3', '80d1c6070a7d', 'someuuid2', 'Fine, thank you', '2023-11-27 12:00:00', NULL);
查询
SELECT
u.id AS user_id
, u.name AS user_name
, m.ad AS ad_id
, a.owner_id AS ad_owner_id
, m.content AS last_message_content
, m.created_at AS last_message_created_at
, COUNT(CASE WHEN m.read_at IS NULL THEN 1 END) AS unread_messages_count
FROM users u
JOIN messages m ON u.id = m.sender
OR u.id = m.receiver
JOIN ads a ON m.ad = a.id
WHERE u.id = '80d1c6070a7d' -- ID to compare with (logged in user's ID)
GROUP BY
u.id
, u.name
, m.ad
, a.owner_id
, m.content
, m.created_at
ORDER BY
m.created_at DESC
结果
用户ID | 用户名 | 广告ID | ad_owner_id | 最后消息内容 | 最后消息创建时间 | 未读消息数 |
---|---|---|---|---|---|---|
80d1c6070a7d | 用户1 | ad3 | someuuid3 | 好的,谢谢 | 2023-11-27 12:00:00 | 1 |
80d1c6070a7d | 用户1 | ad2 | someuuid2 | 你好吗? | 2023-11-27 11:00:00 | 1 |
80d1c6070a7d | 用户1 | 广告1 | 80d1c6070a7d | 嗨 | 2023-11-27 10:02:00 | 1 |
80d1c6070a7d | 用户1 | 广告1 | 80d1c6070a7d | 你好 | 2023-11-27 10:00:00 | 0 |