2012-09-20 50 views
1

我在我的网站上有一个精选部分,其中包含三种类型的精选文章:正常,大和小。目前,我取了三种类型的三个单独的查询,像这样:Rails SQL查询优化

@featured_big_first = Post.visible.where(pinged: 1).where('overlay_type =?', :big).limit(1) 
@featured_big_first = Post.visible.where(pinged: 1).where('overlay_type =?', :small).limit(1) 
@featured_big_first = Post.visible.where(pinged: 1).where('overlay_type =?', :normal).limit(5) 

基本上我寻找一个查询,将在这三个结合,一个取1大,1小,5例正常帖子。

回答

1

我不认为这是可能的,但你可以使用scope哪个更轨的方式来编写代码

而且很可能只是错字,但你重新分配@featured_big_first所以它将包含的最后的数据查询只

在post.rb

scope :overlay_type_record lamda{|type| joins(:visible).where(["visible.pinged=1 AND visible.overlay_type =", type])} 

和在控制器

@featured_big_first = Post.overlay_type_record(:big).limit(1) 
@featured_small_first = Post.overlay_type_record(:small).limit(1) 
@featured_normal_first = Post.overlay_type_record(:normal).limit(5) 
+1

感谢您的建议,我会执行它。在接受你的答案之前,我会等一下,b/c我相信这可以通过使用'UNION'的自定义sql查询来实现。 – zevstatiev

+0

当然是的,即使我想学习一件新的东西:) – Salil

2

如果您不想订购,我会很惊讶。就像你所拥有的那样,它应该找到一个随机的,随机的大的随机法线。

是的,你可以使用UNION。但是,您将必须执行SQL。查看三个查询中每个查询的SQL日志,然后执行一个字符串的SQL查询,这个字符串是UNION之间的三个查询的每一个。它可能工作,或者它可能有限制的问题。

在SQL中可以通过将表连接到它自己,在该表的另一个别名上执行一个group,在另一个别名表为< = group by table并添加having子句的情况下< =表的数量超出限制。

所以,如果你有职位表的简单查询(不可见光和ping的条件),并想与最新的created_at日期的记录,那么正常的查询是:

SELECT posts1.* 
FROM posts posts1, posts posts2 
WHERE posts2.created_at >= posts1.create_at 
    AND posts1.overlay_type = 'normal' 
    AND posts2.overlay_type = 'normal' 
GROUP BY posts1.id 
HAVING count(posts2.id) <= 5 

借此SQL,并添加条件以显示和ping,记住为post1和posts2使用条件。

然后写出大小版本和UNION它们在一起。

我会坚持三个数据库调用。