替代在搜索查询中追加内部联接

时间:2015-09-02 15:17:15

标签: sql postgresql inner-join

在搜索帖子时,用户可以从要筛选的类别列表中进行选择,这会返回与所有选定类别相关的帖子。

SELECT *
FROM posts
INNER JOIN category_joins as filter_categories_join
  ON filter_categories_join.categorizable_id = posts.id 
  AND filter_categories_join.categorizable_type = 'Post'
INNER JOIN categories as filter_categories 
  ON filter_categories.id = filter_categories_join.category_id
INNER JOIN category_joins as categories_join_1
  ON categories_join_1.categorizable_id = posts.id
  AND categories_join_1.categorizable_type = 'Post'
INNER JOIN categories as categories_1
  ON categories_1.id = categories_join_1.category_id
INNER JOIN category_joins as categories_join_2
  ON categories_join_2.categorizable_id = posts.id
  AND categories_join_2.categorizable_type = 'Post'
INNER JOIN categories as categories_2
  ON categories_2.id = categories_join_2.category_id
WHERE filter_categories.lft BETWEEN 14 AND 115
  AND categories_1.lft BETWEEN 133 AND 134
  AND categories_2.lft BETWEEN 137 AND 138

有没有办法避免为每个类别过滤器附加内部联接?

更新:

这里的关联描述:

  • posts有很多categories
  • postscategoriescategory_joins可分类相关
  • categories有许多postscategory_joins

1 个答案:

答案 0 :(得分:0)

不确定为什么要复制不必要的JOINS。您的查询可以简化为

SELECT p.*
FROM posts p
INNER JOIN category_joins cj
  ON cj.categorizable_id = p.id 
  AND cj.categorizable_type = 'Post'

INNER JOIN categories c
  ON c.id = cj.category_id
AND c.lft BETWEEN 14 AND 115
    INNER JOIN categories c1
  ON c1.id = cj.category_id
  AND c1.lft BETWEEN 133 AND 134
INNER JOIN categories c2
  ON c2.id = cj.category_id
 AND c2.lft BETWEEN 137 AND 138;