所以我有以下情况:
我有一个帖子模型,总是有2个或4个参数
class Post < ActiveRecord::Base
# has two columns, status and published (boolean)
has_many :arguments
end
和参数模型
class Argument < ActiveRecord::Base
# has moderated column (boolean) and text
belongs_to :post
end
我想知道我是否可以编写查询来获取具有以下条件的帖子:
1)帖子有未经模仿的参数,其中第一个按id(not updated_at)排序,属于id = 5
用户(例如)
------或------
2)帖子status = 1 and published = true
PS:我正在使用PostgreSQL。
答案 0 :(得分:1)
转换为SQL:
SELECT p.*
FROM posts p
LEFT JOIN (
SELECT DISTINCT ON (post_id)
post_id, user_id
FROM arguments
WHERE moderated = FALSE
ORDER BY post_id, id
) a ON a.post_id = p.id AND a.user_id = 5
WHERE a.post_id IS NOT NULL OR -- condition 1
(a.status = 1 and a.published); -- condition 2
DISTINCT ON
的详细信息:
LEFT JOIN
?如果只有条件1)
,我们可以简化:
SELECT p.*
FROM posts p
JOIN (
SELECT DISTINCT ...
) a ON a.post_id = p.id AND a.user_id = 5;
但是您添加了替代(非附加)条件2)
。如果我们使用普通[INNER] JOIN
,那么未通过条件1)
的帖子将立即从选择中删除,永远不会获得第二次机会。我添加了多余的括号(operator precedence对我们来说没有括号)和换行符指出这是&#34;另一种方式在&#34;:
(a.status = 1 and a.published)
当然,我们现在必须添加条件1)
的检查:
a.post_id IS NOT NULL
这不会重复行,因为子查询每个帖子返回正好1或0 行(而不是更多)。
这是一种解决方法。应该是每个帖子(2 - 4)只有少数属性和一些非常重要的限定属性的绝佳选择。根据您的实际数据分布,可能还有其他更快的查询技术: