I'll start off with the schema:
CREATE TABLE CustomersActions (
`caID` int(10) unsigned NOT NULL AUTO_INCREMENT primary key,
`cusID` int(11) unsigned NOT NULL,
`caTimestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
)
CREATE TABLE `Assignments` (
`asgID` int(10) unsigned NOT NULL AUTO_INCREMENT primary key,
`cusID` int(11) unsigned NOT NULL,
`asgAssigned` date DEFAULT NULL,
`astID` int(10) unsigned NOT NULL
)
CREATE TABLE `AssignmentStatuses` (
`astID` int(10) unsigned NOT NULL AUTO_INCREMENT primary key,
`astStatus` varchar(255) DEFAULT ''
)
My original query is:
SELECT DISTINCT
ca.cusID
FROM
CustomersActions ca
WHERE
NOT EXISTS (
SELECT
TRUE
FROM
Assignments asg
NATURAL JOIN AssignmentStatuses
WHERE
asg.cusID = ca.cusID
AND (
DATE_ADD(asgAssigned, INTERVAL 6 DAY) > NOW()
OR astStatus IN('Not contacted', 'Follow-up')
)
)
What this does is select all cusID entries from CustomersActions if said Customer does not have a row in Assignments that is in "Not contacted" or "Follow-up" (for any date range) OR has an assignment of any status from less than six days ago.
I tried writing the same query using LEFT JOIN to exclude from Assignments like so:
SELECT DISTINCT
ca.cusID
FROM
CustomersActions ca
LEFT JOIN (
Assignments asg
NATURAL JOIN AssignmentStatuses
) ON (ca.cusID = asg.cusID)
WHERE
asgID IS NULL
OR DATE_ADD(asgAssigned, INTERVAL 6 DAY) < NOW()
OR astStatus IN('Not contacted', 'Follow-up')
The problem is that it's possible for a customer to have multiple entries in Assignments so a cusID can be selected even if they have an existing row that should force them to be excluded. This makes sense to me, and the NOT EXISTS solves this problem.
What I'm wondering is if there is a way to perform a single query that has the same effect as the query when using NOT EXISTS. That is, a customer should be excluded if they have any rows that satisfy the exclusion condition, not only if all of their rows satisfy the exclusion condition (or if they have none).