1

スキーマから始めます。

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 つでもあれば、その顧客を除外する必要があります。

4

1 に答える 1

0

NOT IN次のような句を使用してみましたか。

SELECT DISTINCT
  ca.cusID
FROM
 CustomersActions ca
WHERE cusID    
 NOT IN (
    SELECT
       cusID
    FROM
       Assignments asg
       INNER JOIN AssignmentStatuses ast
       ON asg.astID = ast.astID
       WHERE
          DATE_ADD(asgAssigned, INTERVAL 6 DAY) > NOW()
          OR astStatus IN('Not contacted', 'Follow-up')
 )
于 2013-06-24T00:29:40.720 に答える