SELECT ...
FROM email_list l
LEFT JOIN email_list_recipient r ON l.list_id = r.parent_id
WHERE r.parent_id IS NULL
Idé: Du left-joinar alla mottagare mot listorna, och eftersom det är en left join så får du även med listor utan mottagare. När detta sker blir r.parent_id null eftersom det uppenbart inte finns nägra rader i email_list_recipient att joina. Och det kollar du sedan efter i where-kriteriet.
Nja, nu kanske jag inte förklarade så bra, men finns det en lista i den första tabellen finns det även MINST en mottagare, så parent_id kan inte vara NULL, aldrig.
Det som ställer till det är att bland e-postadresserna som tillhör en lista, så kan rpt_sent antingen vara NULL (inte skickar) eller ett datum. Jag ska bara hämta ut alla listor där rpt_sent är NULL för samtliga mottagare, dvs. listan får inte vara "påbörjad".
Det känns ju som om jag måste räkna antal rader i email_list_recipient och kontrollera att alla rpt_sent är NULL. Då bör jag på något sätt köra en COUNT() på något sätt.
Det som dessutom ställer till det ännu mer - listan får inte redan vara "vald" som lista till ett annat mail.
Men det känns som om jag måste lösa problem #1 innan jag krånglar till allt för mycket.
SELECT
a.list_id, a.list_name,
b.*
FROM email_list a
INNER JOIN email_list_recipient b
ON a.list_id = b.parent_id
WHERE NOT EXISTS (
SELECT 1 FROM email_list_recipient
WHERE parent_id = a.list_id
AND rpt_sent IS NOT NULL
)
GROUP BY b.parent_id
ORDER BY
a.list_created ASC;
Har testat att sätta alla eller några mottagare per lista som "skickat" och då exkluderas listan, vilket stämmer.
Kan man skriva ovanstående på något vettigare sätt?
Kan man skriva ovanstående på något vettigare sätt?
Jo, man kan skippa hela joinen och ändå få ut samma resultat:
SELECT
a.list_id, a.list_name
FROM email_list a
WHERE NOT EXISTS (
SELECT 1 FROM email_list_recipient
WHERE parent_id = a.list_id
AND rpt_sent IS NOT NULL
)
ORDER BY
a.list_created ASC;
Nja... Det där kan potentiellt vara en prestandadödare. Prova:
SELECT
l.list_id, l.list_name,
FROM email_list l
INNER JOIN email_list_recipient r
ON l.list_id = r.parent_id
GROUP BY l.list_id
HAVING COUNT(r.rpt_sent) = 0
Tricket är dels att köra having, som evalueras efter group by, och dels att räkna count på r.rpt_sent istället för r, vilket räknar antalet rader där r.rpt_sent inte är null.