从映射表中选择

时间:2013-12-30 00:03:29

标签: mysql sql

我有3张桌子,

categories:
ID, category
"1","Cars"
"2","Trucks"
"3","Bikes"
"4","Planes"
"5","Boats"

users:
ID, username
"1","john"
"2","bob"
"3","billy"

users_categories:
ID, userid, categoryid
"1","1","1"
"2","1","2"
"3","2","2"
"4","3","3"

现在我需要选择具有多个类别(我指定的)的用户,所以在这个例子中,我需要一个只选择具有类别1和2的用户“john”的查询。我将传递我的类别需要在查询中。即1和2。

2 个答案:

答案 0 :(得分:2)

如果需要两个以上的类别,此查询会为所需用户提供:

SELECT userid
FROM user_categories
WHERE 
   categoryid IN (1,2)
GROUP BY userid
HAVING COUNT(*) = 2;

注意:having count(*) = xx必须等于传递给IN ( ... )列表的多个类别。

要检索用户名,请将以上查询加入users表:

SELECT u.*
FROM users u
JOIN (
  SELECT userid
   FROM user_categories
   WHERE 
      categoryid IN (1,2)
   GROUP BY userid
   HAVING COUNT(*) = 2
) q
ON u.id = q.userid;

演示:http://www.sqlfiddle.com/#!2/58651/4

答案 1 :(得分:1)

编辑:meh,错过了有关选择用户名的详细信息,而不是用户名约束。

这是正确答案:

SELECT * FROM `users_categories` AS `uc`
INNER JOIN `users` AS `u` ON `u`.`ID`=`uc`.`userid`
WHERE `uc`.`categoryid` IN (1,2)
GROUP BY `uc`.`userid`
HAVING COUNT(`uc`.`userid`) >= 2

小提琴:http://sqlfiddle.com/#!2/8fdca/9

出于历史目的而留下原始答案。


是的,这可以通过表连接实现。

约束为usernamecategoryid ... john

SELECT `c`.* FROM `users` AS `u`
INNER JOIN `users_categories` AS `uc` ON `uc`.`userid`=`u`.`ID` AND `uc`.`categoryid` IN (1,2)
INNER JOIN `categories` AS `c` ON `c`.`ID`=`uc`.`categoryid`
WHERE `u`.`username`='john';

小提琴:http://sqlfiddle.com/#!2/8fdca/1


如果您删除categoryid约束(以获取给定用户名的所有类别),此次删除AND uc.categoryid IN (1,2) ... billy ,查询也会有效:

SELECT `c`.* FROM `users` AS `u`
INNER JOIN `users_categories` AS `uc` ON `uc`.`userid`=`u`.`ID`
INNER JOIN `categories` AS `c` ON `c`.`ID`=`uc`.`categoryid`
WHERE `u`.`username`='billy';

小提琴:http://sqlfiddle.com/#!2/8fdca/3


此外,如果你已经知道用户的ID,那么现在可以进一步简化......对于 bob (id#2):

SELECT `c`.* FROM `users_categories` AS `uc`
INNER JOIN `categories` AS `c` ON `c`.`ID`=`uc`.`categoryid`
WHERE `uc`.`userid`=2;

小提琴:http://sqlfiddle.com/#!2/8fdca/5