查找属于多个类别的项目

时间:2015-01-21 16:50:22

标签: sql postgresql

我有一个projects表(列idname),一个categories表(列idname)和一个加入表projects_categories(列project_idcategory_id)。

我想编写一个返回属于一组类别的所有项目的查询。例如,如果我有

projects
id name
1  foo
2  bar
categories
id name
1  bee
2  gee
projects_categories
project_id category_id
1          1
1          2
2          1

我想编写一个返回项目的查询" foo"如果我传递类别ID 1和2.我尝试了以下查询,但它返回属于类别1或2的所有项目,而不是类别1和2。

SELECT "projects".* 
FROM "projects" 
INNER JOIN "projects_categories" ON "projects_categories"."project_id" = "project"."id" 
WHERE "projects_categories"."category_id" IN (1, 2)

以下查询不会返回任何结果:

SELECT "projects".* 
FROM "projects" 
INNER JOIN "projects_categories" ON "projects_categories"."project_id" = "project"."id" 
WHERE "projects_categories"."category_id" = 1
  AND "projects_categories"."category_id" = 2

我理解为什么这些查询会返回这些结果,但无法弄清楚如何编写我需要的查询。

2 个答案:

答案 0 :(得分:2)

您可以尝试EXISTS

SELECT "p".* 
FROM "projects" "p" 
WHERE EXISTS ( 
    SELECT *
    FROM "projects_categories" "pc" 
    WHERE "pc"."category_id" IN (1, 2)
      AND "pc"."project_id" = "p"."id"
    GROUP BY "pc"."project_id" 
    HAVING  COUNT(DISTINCT "pc"."project_id" ) = 2)
)

JOIN

SELECT "p".* 
FROM "projects" "p" 
JOIN ( 
    SELECT "pc"."project_id" 
    FROM "projects_categories" "pc" 
    WHERE "pc"."category_id" IN (1, 2)
    GROUP BY "pc"."project_id" 
    HAVING  COUNT(DISTINCT "pc"."project_id" ) = 2)
) "tpc" ON "tpc"."project_id" = "p"."id"

IN

SELECT "p".* 
FROM "projects" "p" 
WHERE "p"."id" IN ( 
    SELECT "pc"."project_id"
    FROM "projects_categories" "pc" 
    WHERE "pc"."category_id" IN (1, 2)
    GROUP BY "pc"."project_id" 
    HAVING  COUNT(DISTINCT "pc"."project_id" ) = 2)
)

答案 1 :(得分:0)

问题是查询正在查看同一个表和列,并尝试使用两个不同的值。这将分离两个不同的条件,然后将它们组合成一个结果集。

SELECT  A.ProjectName, A.CategoryId, B.CategoryId 
FROM    
(SELECT P.Name [ProjectName], PC.CategoryId, PC.ProjectId 
     FROM   @Projects P
            INNER JOIN @Project_Categories PC
                ON PC.ProjectId = P.ID
     WHERE  PC.CategoryId = 1
    ) A
    INNER JOIN (SELECT  P.Name [ProjectName], PC.CategoryId, PC.ProjectId
                FROM    @Projects P
                        INNER JOIN @Project_Categories PC
                            ON PC.ProjectId = P.ID
                WHERE   PC.CategoryId = 2
               ) B
        ON A.ProjectId = B.ProjectId