Rails/SQL帮助:三个表,根据另一条记录的存在情况进行选择和排序
使用ActsAsTaggableOn gem,标记对象是模板。 加上这些协会:Rails/SQL帮助:三个表,根据另一条记录的存在情况进行选择和排序,sql,ruby-on-rails,activerecord,rails-activerecord,querying,Sql,Ruby On Rails,Activerecord,Rails Activerecord,Querying,使用ActsAsTaggableOn gem,标记对象是模板。 加上这些协会: class Template acts_as_taggable has_many :template_designs end class Pins belongs_to :template belongs_to :tag end class Tags has_many :taggings end 目标:一组准备分页的模板,用户在其中选择一个标记,我们找到与该标记匹配的所有模板,并根据同一标记
class Template
acts_as_taggable
has_many :template_designs
end
class Pins
belongs_to :template
belongs_to :tag
end
class Tags
has_many :taggings
end
目标:一组准备分页的模板,用户在其中选择一个标记,我们找到与该标记匹配的所有模板,并根据同一标记和模板是否存在于pin中对它们进行排序,trues位于顶部
编辑-简化和解释
考虑到模板是用标记标记的,并且这些标记可能有也可能没有Pin,我需要选择所有带有X标记的模板,并对它们进行排序,无论该标记是否具有Pin布尔排序,顶部为trues。一种方法是在存在表达式时将外部联接与大小写一起使用:
select templates.*, case when exists
(select pins.id
from pins
where pins.tag_id = tags.id
and pins.template_id = templates.id) then true else false end as pinned
from templates, taggings, tags, pins
where templates.id = taggings.template_id
and taggings.tag_id = tags.id
and tags.name = 'funny';
以下是用于此的活动记录语法:
>> Template.left_outer_joins(:tags)
.where(tags: {name: 'funny'})
.select(:id, :name,
"case when exists
(select pins.id from pins
where pins.tag_id = tags.id
and pins.template_id = templates.id)
then true else false end as pinned")
.map {|t| [t.id, t.name, t.pinned] }
[... sql output ...]
=> [[1, "template1", true], [2, "template2", false]]
请分享示例数据,查询您尝试过的和想要的输出。尝试过多种方法,但对我来说不起作用。没有指定我正在使用的数据库,它是Postgres,并且它不喜欢Case When返回值的别名。此外,将该方法应用于这个更简单的查询,order by也没有起作用:选择id,存在时按案例从订单中总计选择id,从订单中总计。总计>100000,然后为true ELSE false ENDI现在正在研究动态查询生成,以解决这个有趣的问题。不过,谢谢你的帮助。@bazfer我很惊讶这种情况/当构造不适合你时。。。我也在使用Postgres 9.6,但我可能误解了模式。我添加了我正在使用的模式,欢迎更正。它很有效!只需添加“按固定描述订购”。万分感谢。哦,很好,你说得对@bazfer,我忘了订单条款。听起来不错!