2017-01-30 52 views
0

所以我查詢的目標:複雜的ActiveRecord查詢經過許多比較日期時間很多關係

抓取所有那些沒有自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 > ?', 30.days.ago)條款。如果我運行沒有該子句的查詢,它將返回完全相同的結果。

經過多日的審議之後,似乎最簡單的方法就是讓所有30天或更早前舉行過會議的客戶,然後從該陣列中減去最後一次會議的客戶30天,如:

user_clients.without_recent_meetings - user_clients.with_recent_meetings 

有沒有辦法在一個查詢中這樣做,因爲這樣意味着必須兩次運行一個複雜的查詢?

回答

0

試試這個

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)