3

我正在创建一个应用程序,它将为电子邮件营销活动生成列表。我有用于联系人、电子邮件和活动的表格。一个活动有很多电子邮件,一个联系人有很多电子邮件。该电子邮件与联系人和活动相关。基本上是一个多对多关系的表,除了我在表中有其他字段用于电子邮件结果(单击、打开、取消订阅等)。还有其他桌子,但这是我遇到麻烦的地方。

我正在尝试将 NOT IN 与子查询一起使用,以获取自特定日期以来未收到电子邮件的联系人列表以及其他条件。一个示例查询是这样的:

SELECT * 
FROM `contact` `t` 
WHERE (unsubscribed='1')
  AND t.id NOT IN 
   (SELECT distinct contact_id 
    FROM email, campaign 
    WHERE email.campaign_id = campaign.id 
      AND campaign.date_sent >= '2012-07-12') 
ORDER BY rand() 
LIMIT 10000

这将返回 0 结果。但是,如果我运行第一个条件:

select id 
from contact 
where unsubscribed=1

我有 9075 行。然后,如果我单独运行子查询:

SELECT distinct contact_id 
FROM email, campaign 
WHERE email.campaign_id = campaign.id 
  AND campaign.date_sent >= '2012-07-12'

我有 116612 行。在每个结果中,我最终得到 826 个重复值。据我了解,这意味着 9075-826=8249 记录是 unsubscribed=1 而不是在第二个查询中。所以,我的第一个查询应该返回 8249 个结果,但它返回 0。我一定是查询的结构错误或使用了错误的运算符,但我终其一生都无法弄清楚如何做到这一点。

任何人都可以帮忙吗?非常感谢,因为这让我难倒了 3 天!:)

4

3 回答 3

9

这是因为

SELECT 1 FROM DUAL WHERE 1 NOT IN (NULL, 2) 

不会返回任何东西,而

SELECT 1 FROM DUAL WHERE 1 NOT IN (2)

将要。

请查看MYSQL中的NOT IN和的行为。NULL

为了您的担心,您应该使用NOT EXISTS而不是NOT IN

SELECT * FROM `contact` `t` 
WHERE (unsubscribed='1')
AND NOT EXISTS (
    SELECT * FROM email, campaign 
    WHERE 
        email.campaign_id = campaign.id 
    AND campaign.date_sent >= '2012-07-12'
    AND t.id = contact_id
) 
ORDER BY rand() 
LIMIT 10000
于 2012-08-02T18:35:01.123 回答
3

只是在这上面浪费了几个小时和几根头发。

无法让“不存在”像提到的公认答案那样工作。但是,您可以简单地在

WHERE “您正在聚合的字段不是 NULL ”,并且完成了这项工作。

SELECT * 
FROM `contact` `t` 
WHERE (unsubscribed='1')
  AND t.id NOT IN 
   (SELECT distinct contact_id 
    FROM email, campaign 
    WHERE email.campaign_id = campaign.id 
      AND campaign.date_sent >= '2012-07-12'
      AND contact_id is not NULL          ###*************added line
) 
ORDER BY rand() 
LIMIT 10000
于 2017-12-21T12:15:47.270 回答
0
select c.*, e.id from contact as c 
left join email as e on c.id = e.contact_id and e.date_sent >= '2012-07-12' 
where e.id is null and c.unsubscribed = 1

我认为campaign.date_sent 是一个错字?必须是 email.date_sent?

于 2012-08-02T16:03:04.207 回答