在我的应用中,用户
CREATE TABLE users (
id bigserial PRIMARY KEY,
username varchar(50) NOT NULL
);
可以发送消息
CREATE TABLE messages (
id bigserial PRIMARY KEY,
from_id bigint NOT NULL REFERENCES users ON DELETE RESTRICT,
body text NOT NULL CHECK (body <> ''),
created_at timestamp(0) NOT NULL DEFAULT LOCALTIMESTAMP(0)
);
对许多收件人
CREATE TABLE message_recipients (
message_id bigint NOT NULL REFERENCES messages ON DELETE CASCADE,
user_id bigint NOT NULL REFERENCES users ON DELETE RESTRICT,
PRIMARY KEY (message_id, user_id)
);
请参阅this SQL Fiddle。
我如何SELECT
一组用户之间的最新消息(例如20条)?
例如,如何在用户1,2和3之间获取20条最新消息?即,如何将消息限制为1已发送给2&amp; 2的最新消息。 3,2已发送给1&amp; 3和3已经发送给1&amp; 2?
注意:我不想将消息分配给频道。我想通过发件人和他们过滤它们接收机。
答案 0 :(得分:1)
首先汇总每条消息的参与者,然后您可以匹配参与者列表。
WITH target_group (members) AS (
VALUES (ARRAY [1, 2, 3] :: BIGINT [])
), message_group AS (
SELECT
-- message id
m.id,
-- aggregate the ids of all message parties
array_agg(mr.user_id) || m.from_id AS members
FROM message_recipients mr
JOIN messages m ON m.id = mr.message_id
JOIN target_group tg ON tg.members @> ARRAY [m.from_id]
GROUP BY m.id
)
SELECT
m.id,
m.body
FROM message_group mg
JOIN messages m ON m.id = mg.id
JOIN target_group tg ON tg.members @> mg.members AND array_length(tg.members, 1) = array_length(mg.members, 1)
ORDER BY m.id DESC
LIMIT 20;