Rails/SQL帮助:三个表,根据另一条记录的存在情况进行选择和排序

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 目标:一组准备分页的模板,用户在其中选择一个标记,我们找到与该标记匹配的所有模板,并根据同一标记

使用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
目标:一组准备分页的模板,用户在其中选择一个标记,我们找到与该标记匹配的所有模板,并根据同一标记和模板是否存在于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,我忘了订单条款。听起来不错!