Rails 4 .where.not

时间:2015-09-22 04:05:00

标签: mysql sql ruby-on-rails activerecord

pry(main)> Loan.joins(:statistics).where(state: <some states>).where.not(statistics: {state: <some other states>}).order(created_at: "desc").last.statistics.map(&:state)

2015-09-21 20:53:54,423|65310|DEBUG|development| -   Loan Load (0.9ms)  SELECT  `loans`.* FROM `loans` INNER JOIN `statistics` ON `statistics`.`loan_id` = `loans`.`id` WHERE `loans`.`state` IN ('started', 'pending_declined') AND (`statistics`.`state` NOT IN ('prequalified', 'conditionally_approved', '4506t_results_uploaded', 'customer_forms_uploaded', 'ready_for_etran', 'etran_verified', 'forms_to_be_verified', 'forms_verified', 'credit_memo_entered', 'loandoc_generated', 'loandoc_completed', 'loandoc_customer_received_need_signatures', 'signatures_checked_and_uploaded', 'boarded'))  ORDER BY `loans`.`created_at` ASC LIMIT 1
2015-09-21 20:53:54,426|65310|DEBUG|development| -   Statistic Load (0.3ms)  SELECT DISTINCT `statistics`.* FROM `statistics` WHERE `statistics`.`loan_id` = 97
=> ["started", "prequalified", "conditionally_approved", "customer_forms_uploaded", "ready_for_etran", "pending_declined"]

所以,也许我不明白这里发生了什么......我要求SQL找到一些他们的统计数据包含某些值的贷款。在这个例子中,我想要遗漏任何统计为prequalified的贷款,但是,正如您从打印输出中看到的那样,贷款#统计数据确实有prequalified以及其他几个我想退出。

有人可以对此有所了解吗?我已经和它斗了好几个小时了,我的脑袋正在旋转。

2 个答案:

答案 0 :(得分:0)

因为你使用了last.statistics。这意味着贷款对象的结果将与统计数据结合,而您之前已创建条件。 查看您的上一个结果查询:

Statistic Load (0.3ms)  SELECT DISTINCT `statistics`.* FROM `statistics` WHERE `statistics`.`loan_id` = 97

删除你的last.statistics

Loan.joins(:statistics).where(state: <some states>).where.not(statistics: {state: <some other states>}).order(created_at: "desc").map(&:state)

或 如果你想在map(&state)

之前添加条件来确定你需要的一些贷款
Loan.joins(:statistics).where(state: <some states>).where.not(statistics: {state: <some other states>}).where("loans.id IN (97)").order(created_at: "desc")

答案 1 :(得分:0)

您查询返回longpress()Loan的产品,因此它仍然会返回某些 Statistic但没有您的状态的Loan条记录指定。

如果您只希望Statistic在这些状态上没有Loan,那么您可能希望您的SQL成为这一行:

Statistic

我的SQLfu并不是我引以为荣的,所以这可能不是最优化的查询,但它应该得到你期望的结果。

您可以将其转换为SELECT loans.*, FROM loans LEFT OUTER JOIN ( SELECT statistics.loan_id, COUNT(*) count FROM quotes WHERE statistics.state IN ('prequalified', 'conditionally_approved') GROUP BY statistics.loan_id ) statistics ON statistics.loan_id = loans.id WHERE loans.state IN ('started', 'pending_declined') AND statistics.count IS NULL; 查询界面,但不幸的是,子查询和ActiveRecord实际上并不受支持,至少不是我们要使用它的方式将是这样的:

LEFT JOIN

如果您不熟悉join_query = <<SQL LEFT OUTER JOIN ( SELECT statistics.loan_id, COUNT(*) AS count FROM statistics WHERE statistics.state IN (<<state>>) ) statistics ON loans.id = statistics.loan_id SQL Loan .joins(join_query) .where(statistics: { count: null }) .where(state: <<somestate>>) .order(created_at: :desc) ,则<<SQL ... SQLHeredoc