选择与第二个表中的行集连接的行

时间:2009-12-13 20:57:54

标签: sql mysql database

我有三张桌子:

project (idproject, name)

color (idcolor, name)

project_has_color (idproject, idcolor)

现在我需要选择与一组颜色相关的项目,例如:blue(1),red(2),green(3):

SELECT p.idproject, p.name
FROM project p, project_has_color c
WHERE p.idproject=c.idproject AND c.idcolor IN (1,2,3)

给了我与一个或多个给定idcolor连接的项目,我需要与所有相关的项目 - 但我无法弄清楚如何实现这一目标?

2 个答案:

答案 0 :(得分:5)

使用JOIN是最可靠的方式:

SELECT p.idproject, 
       p.name
  FROM PROJECT p
  JOIN PROJECT_HAS_COLOR phc ON phc.idproject = p.idproject
  JOIN COLOR c1 ON c1.idcolor = phc.idcolor
               AND c1.idcolor = 1
  JOIN COLOR c2 ON c2.idcolor = phc.idcolor
               AND c2.idcolor = 2
  JOIN COLOR c3 ON c3.idcolor = phc.idcolor
               AND c3.idcolor = 3

使用:

  SELECT p.idproject, 
         p.name
    FROM PROJECT p
    JOIN PROJECT_HAS_COLOR phc ON phc.idproject = p.idproject
    JOIN COLOR c ON c.idcolor = phc.idcolor
   WHERE c.idcolor IN (1, 2, 3)
GROUP BY p.idproject, p.name
  HAVING COUNT(*) = 3

...依靠您的数据模型阻止idcolor值多次与项目关联。您不能在MySQL中使用HAVING COUNT(DISTINCT *),因此同一项目的2个以上关系将复制idcolor值将返回误报。

答案 1 :(得分:0)

这可能有用

SELECT p.idproject, p.name
FROM project p JOIN project_has_color c USING (idproject)
WHERE c.idcolor IN (1,2,3)
HAVING count(*)=3;

前提是项目不能与颜色相关联两次(即(idproject,idcolor)是唯一的)。或

HAVING
    count(CASE WHEN c.idcolor=1 THEN 1 ELSE NULL)>0
    AND count(CASE WHEN c.idcolor=2 THEN 1 ELSE NULL)>0
    AND count(CASE WHEN c.idcolor=3 THEN 1 ELSE NULL)>0;

否则。