【问题标题】:Complex ActiveRecord query comparing datetime through many to many relation通过多对多关系比较日期时间的复杂 ActiveRecord 查询
【发布时间】:2017-06-16 03:28:24
【问题描述】:

所以我的查询目标:

获取自 30 天前以来未开会的单个用户的所有客户。

Client has_many :meetings, through: :contacts 虽然联系人在这里不是很相关。

我的查询如下:

user.clients.where(is_dormant: false).joins(:meetings).distinct.where('meetings.actual_start_datetime <= ?', 30.days.ago).where.not('meetings.actual_start_datetime > ?', 30.days.ago)

产生这个 SQL:

SELECT DISTINCT "clients".* FROM "clients" INNER JOIN "contacts" ON "contacts"."client_id" = "clients"."id" INNER JOIN "meetings" ON "meetings"."contact_id" = "contacts"."id" INNER JOIN "clients_users" ON "clients"."id" = "clients_users"."client_id" WHERE "clients_users"."user_id" = $1 AND "clients"."is_dormant" = $2 AND (meetings.actual_start_datetime <= '2016-12-31 20:29:08.972999') AND (NOT (meetings.actual_start_datetime > '2016-12-31 20:29:08.973484'))  ORDER BY "clients"."name" ASC  [["user_id", 1], ["is_dormant", "f"]]

但它似乎只是忽略了where.not('meetings.actual_start_datetime &gt; ?', 30.days.ago) 子句。如果我在没有该子句的情况下运行查询,它会返回完全相同的结果。

经过多天的考虑,似乎最简单的方法是获取所有在 30 天或更长时间前开会的客户,然后从该数组中减去在过去 30 天开会的客户天,例如:

user_clients.without_recent_meetings - user_clients.with_recent_meetings

有没有办法在一个查询中执行此操作,因为这种方式意味着必须运行两次复杂的查询?

【问题讨论】:

    标签: ruby-on-rails postgresql datetime activerecord


    【解决方案1】:

    试试这个

    user.clients.where(is_dormant: false).joins(:meetings).distinct.where('meetings.actual_start_datetime <= ? AND clients.id not in (select m.client_id from meetings m where m.actual_start_datetime>?)', 30.days.ago) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-09
      • 1970-01-01
      • 2019-11-08
      相关资源
      最近更新 更多