スキーマから始めます。
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 ''
)
私の元のクエリは次のとおりです。
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')
)
)
これが行うことは、前述の顧客が「連絡なし」または「フォローアップ」の行を持たない場合 (任意の日付範囲)、または6 日以内に任意のcusID
ステータスが割り当てられている場合、CustomersActions からすべてのエントリを選択することです。 .Assignments
LEFT JOIN
次のように除外するために使用して同じクエリを作成しようとしましAssignments
た:
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')
問題は、顧客が複数のエントリを持っている可能性があるAssignments
ため、cusID
それらを強制的に除外する必要がある既存の行がある場合でも選択できることです。これは私には理にかなっており、NOT EXISTS
この問題を解決します。
私が疑問に思っているのは、を使用した場合のクエリと同じ効果を持つ単一のクエリを実行する方法があるかどうかですNOT EXISTS
。つまり、すべての行が除外条件を満たしている場合 (または除外条件を満たさない場合) だけでなく、除外条件を満たす行が 1 つでもあれば、その顧客を除外する必要があります。