通过外连接排除所有行?

时间:2013-02-01 22:23:33

标签: mysql

我将从架构开始:

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')
           )
     )

如果所述客户在“未联系”或“跟进”(对于任何日期范围)中的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 个答案:

答案 0 :(得分: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')
 )