pivot表,在正好两行之间查找公共属性

nhjlsmyf  于 2021-06-24  发布在  Mysql
关注(0)|答案(1)|浏览(248)

我有下面的透视表 chat_user 将用户对象连接到聊天对象。

其行为是,任何数量的聊天可能存在,有2个或更多的参与者。我在这里说明了这个案例。我试图制定一个有效的查询,将用户id 16和用户id 29391作为输入,如果存在这样一个chat id,正好这两个用户id参与其中(本例中的chat id 1),则返回它以进行进一步处理。它应该忽略其他用户也参与的匹配,例如chat\u id 2。
由于系统的设计方式,此表可能达到n^2,其中n是用户数,而不考虑群聊。我需要一个能够在合理的syncron响应时间内处理这些数字(可能是数百万行)的查询,当我写出来的时候,这听起来越来越不可能了。
因此,我正在寻找一个mysql向导来告诉我这是否合理,甚至可能,或者我是否应该认真重新设计这种安排。我这样做是为了支持1对1聊天以及群聊天,同时保持完全的引用完整性。我也在尽可能地重用代码,因为这个聊天只是大型web应用程序的一个小组件。我真的是想避免做1对1和小组聊天作为不同的模式与单独的存储和所有,但如果这是疯狂的,那么我没有选择。我以前在使用sql向导时取得了很好的效果,所以我保持乐观。
另外,请进入至少适度的细节,我是相当新手,当谈到sql,所以我可能无法拼凑基本指令在一起。
热释光;dr:以两个用户id作为输入的查询,当且仅当正好有两行匹配给定的用户id和一些共同的聊天id时,才返回一个聊天id。这对一个可能是百万富翁的人来说太难了吗?
编辑::这是我目前的工作

SELECT u1.chat_id
FROM   chat_user u1 
       INNER JOIN chat_user u2 
               ON u1.chat_id = u2.chat_id 
WHERE  (u1.user_id = ? AND u2.user_id = ? ) 
       AND u1.chat_id IN (SELECT chat_id 
                          FROM   chat_user 
                          GROUP  BY chat_id 
                          HAVING Count(chat_id) = 2)

复制粘贴表让任何有兴趣的人快速开始尝试

CREATE TABLE `chat_user` (
  `chat_id` int(10) UNSIGNED NOT NULL,
  `user_id` int(10) UNSIGNED NOT NULL,
  `engaged` tinyint(1) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

INSERT INTO `chat_user` (`chat_id`, `user_id`, `engaged`) VALUES
(1, 16, 1),
(1, 29391, 1),
(2, 16, 1),
(2, 555, 0),
(2, 29391, 1),
(3, 14, 0),
(3, 29391, 1);

ALTER TABLE `chat_user` ADD PRIMARY KEY (`chat_id`,`user_id`);
axkjgtzd

axkjgtzd1#

以下是我的方法:

SELECT u1.chat_id
FROM chat_user AS u1
JOIN chat_user AS u2 
  ON u1.chat_id = u2.chat_id
LEFT JOIN chat_user AS u3 
  ON u3.chat_id = u1.chat_id AND u3.user_id NOT IN (u1.user_id, u2.user_id)
WHERE u1.user_id = ? AND u2.user_id = ? 
 AND u3.chat_id IS NULL;

你需要索引 (user_id, chat_id) 继续 (chat_id, user_id) . 您定义的主键对于后一个索引就足够了。

相关问题