0

我可以用一个包含/包含和一个 id 来限制它

explain SELECT "questions".*
FROM "questions"
INNER JOIN "taggings" ON "taggings"."question_id" = "questions"."id"
INNER JOIN "tags" ON "tags"."id" = "taggings"."tag_id"
WHERE ("tags"."name" IN ('Cats') AND "tags"."id" = 1);

结果

查询计划

 Nested Loop  (cost=5.49..23.95 rows=1 width=1088)
   ->  Hash Join  (cost=5.49..15.67 rows=1 width=1092)
     Hash Cond: (taggings.question_id = questions.id)
     ->  Bitmap Heap Scan on taggings  (cost=4.31..14.45 rows=7 width=8)
           Recheck Cond: (tag_id = 1)
           ->  Bitmap Index Scan on index_taggings_on_tag_id  (cost=0.00..4.30 rows=7 width=0)
                 Index Cond: (tag_id = 1)
     ->  Hash  (cost=1.08..1.08 rows=8 width=1088)
           ->  Seq Scan on questions  (cost=0.00..1.08 rows=8 width=1088)
  ->  Index Scan using index_tags_on_name on tags  (cost=0.00..8.27 rows=1 width=4)
     Index Cond: ((name)::text = 'Cats'::text)
     Filter: (id = 1)
   (12 rows)

我可以使用相同的包含语句来限制它(其中 cat 两次)

explain SELECT "questions".*
FROM "questions"
INNER JOIN "taggings" ON "taggings"."question_id" = "questions"."id"
INNER JOIN "tags" ON "tags"."id" = "taggings"."tag_id"
WHERE ("tags"."name" IN ('Cats')
AND "tags"."name" IN ('Cats'));

结果

查询计划

 Hash Join  (cost=5.49..24.00 rows=1 width=1088)
   Hash Cond: (taggings.question_id = questions.id)
   ->  Nested Loop  (cost=4.31..22.79 rows=7 width=4)
        ->  Index Scan using index_tags_on_name on tags  (cost=0.00..8.27 rows=1 width=4)
              Index Cond: ((name)::text = 'Cats'::text)
     ->  Bitmap Heap Scan on taggings  (cost=4.31..14.45 rows=7 width=8)
           Recheck Cond: (tag_id = tags.id)
           ->  Bitmap Index Scan on index_taggings_on_tag_id  (cost=0.00..4.30 rows=7 width=0)
                 Index Cond: (tag_id = tags.id)
   ->  Hash  (cost=1.08..1.08 rows=8 width=1088)
         ->  Seq Scan on questions  (cost=0.00..1.08 rows=8 width=1088)
(11 rows)

当我尝试按两个包含过滤时,没有结果

explain SELECT "questions".* 
FROM "questions"
INNER JOIN "taggings" ON "taggings"."question_id" = "questions"."id"
INNER JOIN "tags" ON "tags"."id" = "taggings"."tag_id"
WHERE ("tags"."name" IN ('Cats')
AND "tags"."name" IN ('Dogs'));

结果

查询计划

 Result  (cost=0.00..0.01 rows=1 width=0)
   One-Time Filter: false
(2 rows)
4

2 回答 2

3

如果您期望有所不同,我假设您想使用 OR not AND:

...
WHERE tags.name IN ('Cats')
OR tags.name IN ('Dogs')

或者将两个列表合并为一个列表:

...
WHERE tags.name IN ('Cats', 'Dogs')

正如你所拥有的,这在逻辑上是不可能的,因为两个列表中都没有值(你的集合的交集是空的)。

于 2013-10-16T15:37:25.920 回答
0

这是一个非常糟糕的查询。这就是我想要的:

SELECT COUNT("questions"."id"), "questions"."title" FROM "questions"
INNER JOIN "taggings" ON "taggings"."question_id" = "questions"."id"
INNER JOIN "tags" ON "tags"."id" = "taggings"."tag_id"
WHERE ("tags"."name" IN ('Cats','Dogs'))
GROUP BY "questions"."id", "questions"."title"
HAVING COUNT("questions"."id") = 2;

这两个是一个变量,等于数组中值的数量。

于 2013-10-16T18:57:48.223 回答