【问题标题】:Rails 4 OR query with join table using group and havingRails 4 OR 查询与使用组的连接表并具有
【发布时间】:2015-01-21 17:02:25
【问题描述】:

我有一个这样的 Rails 4 查询:

user.positions.where('positions.active = ? OR positions.deadline < ?', false, Date.current).joins(:cvs).where(cvs: {accepted: true}).group(:id).having('COUNT(cvs.id) = 3')

这会产生以下 SQL 查询:

SELECT `positions`.* FROM `positions` INNER JOIN `cvs` ON `cvs`.`position_id` = `positions`.`id` WHERE `positions`.`user_id` = 4 AND (positions.active = 0 OR positions.deadline < '2015-01-21') AND `cvs`.`accepted` = 1 GROUP BY id HAVING COUNT(cvs.id) = 3

我真正需要的是使第二个 where 查询成为 OR 条件,但上面的查询导致 AND 条件。

我还尝试了以下方法:

user.positions.joins(:cvs).where('positions.active = ? OR positions.deadline < ? OR cvs.accepted = 1 GROUP BY id HAVING COUNT(cvs.id) = ?', false, Date.current, 3)

但这是由 Rails 转换为

SELECT  `positions`.* FROM `positions` INNER JOIN `cvs` ON `cvs`.`position_id` = `positions`.`id` WHERE `positions`.`user_id` = 4 AND (positions.active = 0 OR positions.deadline < '2015-01-21' OR cvs.accepted = 1 GROUP BY id HAVING COUNT(cvs.id) = 3)

由于末尾的右括号而引发 sql 语法错误。如果没有左括号和右括号,或者如果将右括号放在“2015-01-21”之后,它会起作用。但我不知道如何告诉 Rails 不要放任何括号。

(我真正想查询的是所有不活跃的职位,或者截止日期已经到的职位,或者一个职位有3个接受的简历)

【问题讨论】:

    标签: sql ruby-on-rails ruby-on-rails-4 join


    【解决方案1】:

    ActiveRecord 不能做到or,但 Arel 可以。神奇的scuttle.io 会解决你的问题:

    Position.select(Position.arel_table[Arel.star]).where(
      Position.arel_table[:user_id].eq(4).or(
        Position.arel_table[:active].eq(0).or(Position.arel_table[:deadline].lt('2015-01-21')).or(Cv.arel_table[:accepted].eq(1))
      )
    ).joins(
      Position.arel_table.join(Cv.arel_table).on(
        Cv.arel_table[:position_id].eq(Position.arel_table[:id])
      ).join_sources
    ).group(:id)
    

    【讨论】:

    • 感谢您的建议。 scuttle.io 似乎是一个很酷的工具,但它生成的查询没有考虑“有 count(cvs.id) = 3”。此外 Position.arel_table[:user_id].eq(4) 并没有真正起作用,因为查询还返回其他用户的位置。
    • 这是having 的语法。 github.com/rails/arel#more-sophisticated-queries 我建议向 scuttle 作者提交一个错误,因为他反应迅速。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多