MySQL查询从多行获取数据

时间:2014-06-24 13:51:23

标签: mysql sql database

我需要从MySQL表中选择一个conversation_id,其中对话中的用户与数组中提供的用户完全匹配,例如(2,5) - 应该返回1作为会话ID。

db表的提取如下:

user_ids (2, 5)

conversation_users:

conversation_id      user_id
1                    2
1                    5
2                    2
2                    6

这可以在一个查询中完成吗?

编辑 - 26.06.2014

实际上,在做了一些测试后,这并不总能正常工作。如果属于对话的用户数多于数组中的用户数,则仍会返回这些用户所属的所有对话。

我希望将数组中的用户与对话中的用户完全匹配。

fiddle

在下面的示例中,会话6和7都返回,但不应返回任何行:

SELECT `conversation_id` FROM `conversation_user` WHERE `user_id` IN (70, 426)
GROUP BY `conversation_id` HAVING COUNT(DISTINCT `user_id`) = 2;


conversation_user_id  conversation_id user_id
14                    6               70
15                    6               29
16                    6               442
17                    6               425
18                    6               426
19                    7               70
20                    7               442
21                    7               426
22                    7               499
23                    7               425
24                    7               29

1 个答案:

答案 0 :(得分:2)

是的,可以使用WHEREGROUP BYHAVING条款的组合来实现这一点:

SELECT conversation_id 
FROM conversation_users
WHERE user_id IN (2,5)
GROUP BY conversation_id
HAVING COUNT(DISTINCT user_id) = 2 

第二个选项

如果一个对话中有两个以上的记录(用户),那么您有几个选择。下面给出了一个选项,其中删除了WHERE子句并使用了GROUP_CONCAT,如下所示:

SELECT `conversation_id` FROM `conversation_user` 
GROUP BY `conversation_id` 
HAVING COUNT(DISTINCT `user_id`) = 2
AND GROUP_CONCAT(DISTINCT `user_id` ORDER BY `user_id` ASC SEPARATOR ',') = '70,426'

但是,这可能不是一种非常灵活的方法,因为它希望用户列表是一个以逗号分隔的有序字符串。

工作小提琴:http://sqlfiddle.com/#!2/4c82d/13

第三个选项

使用子查询来获取仅包含2个用户的对话,而不是GROUP_CONCAT(如上面第2个选项中所述)。然后将此子查询与主表连接,并应用与上面给出的第一个选项中使用的相同的过滤器(WHEREGROUP BY),如下所示:

SELECT `conversation_id` 
FROM `conversation_user` 
JOIN (
  SELECT `conversation_id` t_cid FROM `conversation_user` 
  GROUP BY `conversation_id` 
  HAVING COUNT(DISTINCT `user_id`) = 2
) t
ON t.t_cid = `conversation_user`.`conversation_id`
WHERE `user_id` IN (70, 426)
GROUP BY `conversation_id` 
HAVING COUNT(DISTINCT `user_id`) = 2

应该是更好的方法,因为它不依赖于第二个选项中所需的已排序的逗号分隔列表。

工作小提琴http://sqlfiddle.com/#!2/4c82d/21