2017-01-30 3 views
0

also das Ziel meiner Anfrage zu vergleichen:Complex Active Abfrage Datumzeit durch viele zu viele Beziehung

alle von einem einzigen Benutzer-Clients holen, die nicht gehabt haben, vor 30 Tage ein Treffen ab.

A Client has_many :meetings, through: :contacts obwohl Kontakte hier nicht sehr relevant sind.

Meine Frage lautet wie folgt:

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) 

die diese SQL erzeugt:

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"]] 

Aber es scheint, nur um die where.not('meetings.actual_start_datetime > ?', 30.days.ago) Klausel zu ignorieren. Wenn ich die Abfrage ohne diese Klausel ausführe, gibt sie das exakt gleiche Ergebnis zurück.

Nach vielen Tagen des Nachdenkens scheint es der einfachste Weg, dies zu tun, erhalten alle Kunden, die eine Sitzung vor 30 oder mehr Tagen hatten, dann subtrahieren von diesem Array die Kunden, die eine Sitzung in der letzten hatte 30 Tage, zum Beispiel:

user_clients.without_recent_meetings - user_clients.with_recent_meetings 

gibt es eine Möglichkeit, dies in einer Abfrage zu tun, da auf diese Weise bedeutet, zweimal eine komplexe Abfrage ausführen zu müssen?

Antwort

0

Versuchen Sie dieses

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)