我正在创建一个基于群组的聊天,该聊天要求仅将消息发送给同一群组中的人员。莎拉、詹姆斯和克里斯属于一个组,但不是莎拉、詹姆斯、克里斯和保罗,也不是莎拉和詹姆斯。到目前为止,我是这样建模的:
这是表A,它将把user_id链接到group_id
user_id|group_id
1 | 1
2 | 1
1 | 2
2 | 2
3 | 2
这是表 B,它被存储过程接受为输入
sender_id|recipient_id|text
1 | 2 | Hey
1 | 3 | Hey
表 B 代表一条消息,因此 sender_id 和 text 将相同。这意味着 user_ids 1、2 和 3 位于同一群组对话中,但不是 1 和 2 或 1 和 3。
现在这是棘手的部分。我事先不知道消息本身的 group_id,这是因为从上面的两个表中,需要动态确定该消息是否将分配给现有组(意味着 group_id 存在于 中)表 A 包含 表 B 中的确切 user_ids),或者是否需要创建新组(没有完全匹配)。
这是包含消息的表
group_id|sender_id|message_id|text
? | 1 | ... |Hey
关于如何根据表 A 和 B 确定是否需要创建新的 group_id 有什么建议吗?
我可能会通过发件人+收件人的联合在消息中构建一组用户来解决这个问题,然后将它们与现有组进行匹配并确保数字完全匹配。
类似:
WITH incoming AS (
SELECT *
FROM
(
VALUES (1, 2, N'Hey')
, (1, 3, N'Hey')
) t (sender_id,recipient_id,text)
)
, incoming_group AS (
SELECT vd.sender_id, COUNT(*) OVER() AS cnt
FROM incoming v
CROSS apply (
VALUES(sender_id),(recipient_id)
) vd
GROUP BY vd.sender_id
)
, existing AS (
SELECT *
FROM
(
VALUES (1, 1)
, (2, 1)
, (1, 2)
, (2, 2)
, (3, 2)
) t (user_id,group_id)
)
, existing_group as (
SELECT user_id, group_id
, COUNT(*) OVER(PARTITION BY group_id) AS cnt
FROM existing
)
SELECT eg.group_id AS matching_group
FROM incoming_group ig
LEFT JOIN existing_group eg
ON eg.user_id = ig.sender_id
AND eg.cnt = ig.cnt
GROUP BY eg.group_id, ig.cnt
HAVING COUNT(*) = ig.cnt
如果加入成功,您将获得现有的组ID,否则您将获得0行并可以创建新组等