2016-07-12 5 views
0

Der Versuch, eine Abfrage zu erstellen, um Benutzer auszuwählen, denen der Newsletter nicht per E-Mail zugesandt wurde, wenn der Stapel abläuft. Die Tabelle mail_log erfasst Einträge aus 3 verschiedenen Mailinglisten und verwaltet das Protokoll für die letzten 4-5 Wochen - mit anderen Worten, es sollten mehrere Protokolleinträge für jeden Abonnenten vorhanden sein.Auswählen von Benutzern, denen kein Newsletter gesendet wurde

Ich möchte alle Abonnenten auswählen, die nicht per E-Mail benachrichtigt wurden, wenn der Stapel beim Senden eine Zeitüberschreitung aufweist.

mail_log 
+--------+------------+-------------+------------+---------+ 
| log_id | send_date | location_id | mailing_id | list_id | 
+--------+------------+-------------+------------+---------+ 
location_id is which mailing list 
mailing_id is the specific newsletter 
list_id is the subscriber's id in the mailing list 

mail_list 
+---------+-------+-------+-------+ 
| list_id | fname | lname | email | 
+---------+-------+-------+-------+ 

Ich habe diese Abfrage versucht:

SELECT mail_list.* 
FROM mail_list 
LEFT JOIN mail_log ON mail_log.list_id = mail_list.list_id 
WHERE mail_log.send_date = '2016-07-12' 
AND mail_log.location_id = '2' 
AND mail_log.list_id IS NULL` 

Die Abfrage 0 Ergebnisse liefert, aber eine erfolgreiche Abfrage sollte etwa 700 Ergebnisse zurück.

+0

Ja, eine schamlose Werbemöglichkeit für [Gefahren von Not In] (http://StackOverflow.com/a/32175659) – Drew

+0

Sie müssen auch 'mail_log. *' Auch auswählen - – Zak

+0

WHERE zu UND ändern. Ändern Sie das endgültige UND zu WHERE – Strawberry

Antwort

2

Wenn Sie LEFT JOIN verwenden, müssen Sie die Einschränkungen für die untergeordnete Tabelle in die ON-Klausel einfügen. Andernfalls werden beim Testen dieser Felder nur Nicht-NULL-Zeilen gefunden, was dem AND mail_log.list_id IS NULL-Test widerspricht.

SELECT mail_list.* 
FROM mail_list 
LEFT JOIN mail_log ON mail_log.list_id = mail_list.list_id 
    AND mail_log.send_date = '2016-07-12' 
    AND mail_log.location_id = '2' 
WHERE mail_log.list_id IS NULL 
+0

Danke. Gleich nachdem ich gepostet habe, habe ich festgestellt, dass diese Abfrage auch funktioniert. SELECT * FROM mail_list WHERE list_id NICHT IN (SELECT list_id FROM mail_log WHERE mailing_id = '216') Irgendwelche Rückmeldungen zu welcher Frage ist besser? –

+0

Gewöhnliche Joins sind normalerweise besser als 'WHERE IN (SELECT ...)', weil sie Indizes besser verwenden. Ich weiß nicht ohne weiteres über die relative Leistung von 'WHERE NOT IN'. Benchmark sie. – Barmar

0

SELECT * FROM mail_list WHERE LIST_ID NICHT IN (list_id VON mail_log SELECT WHERE mailing_id = '216')

ist schlimmer, weil mit einem NICHT IN, wird kein Index verwendet werden. Abfrage mit linkem Join könnte list_id, send_date UND location_id als mögliche Indizes für den Join verwenden.

Verwandte Themen