简体   繁体   English

MySQL不在子查询不按预期工作

[英]MySQL NOT IN with subquery not working as expected

I'm creating a application that will generate lists for email marketing campaigns. 我正在创建一个应用程序,它将为电子邮件营销活动生成列表。 I have tables for contacts, emails, and campaigns. 我有联系人,电子邮件和广告系列的表格。 A campaign has many emails and a contact has many emails. 广告系列包含许多电子邮件,而联系人则包含许多电子邮件。 The email is related to a contact and a campaign. 该电子邮件与联系人和广告系列相关。 Basically a table for a MANY to MANY relationship except I have other fields in the table for the result of the email (clicked, opened, unsubscribed, etc). 基本上是一个MANY到MANY关系的表,除了我在表格中有其他字段用于电子邮件的结果(点击,打开,取消订阅等)。 There are also other tables but this is where I'm having the trouble. 还有其他表,但这是我遇到麻烦的地方。

I'm trying to use NOT IN with a subquery to get a list of contacts who have not received an email since a certain date with other conditions. 我正在尝试使用带有子查询的NOT IN来获取自其他条件的特定日期以来未收到电子邮件的联系人列表。 An example query is this: 一个示例查询是这样的:

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

This returns 0 result. 这返回0结果。 However, if I run the first condition: 但是,如果我运行第一个条件:

select id 
from contact 
where unsubscribed=1

I have 9075 rows. 我有9075行。 Then, if I separately run the subquery: 然后,如果我单独运行子查询:

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

I have 116612 rows. 我有116612行。 Out of each of those results, I end up with 826 values that are duplicates. 在每个结果中,我最终得到了826个重复的值。 From what I can understand, this means that 9075-826=8249 records ARE unsubscribed=1 AND NOT IN the second query. 根据我的理解,这意味着9075-826 = 8249条记录取消订阅= 1而不是第二次查询。 So, my first query should be returning 8249 results but it is returning 0. I must be structuring the query wrong or using the wrong operators but I can not for the life of me figure out how to get this right. 所以,我的第一个查询应该返回8249结果,但它返回0.我必须构造错误的查询或使用错误的运算符,但我不能为我的生活弄清楚如何正确。

Can anyone help? 有人可以帮忙吗? So many thanks in advance as this has had me stumped for like 3 days! 非常感谢,因为这让我难以忍受了3天! :) :)

This is because 这是因为

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

won't return anything, whereas 不会返回任何东西,而

SELECT 1 FROM DUAL WHERE 1 NOT IN (2)

will. 将。

Please review the behaviour of NOT IN and NULL in MYSQL. 请查看MYSQL中NOT INNULL的行为。

For your concern you should get away with it using NOT EXISTS instead of NOT IN : 为了您的关注,您应该使用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

Just wasted a few hours and a few hairs on this as well. 这也浪费了几个小时和几根头发。

Was not able to get "NOT exists" to work as the accepted answer mentioned. 无法让“不存在”作为所提到的接受答案而工作。 However, you can simply throw in a NOT NULL in 但是,你可以简单地输入一个NOT NULL

WHERE "field you are aggregating is not NULL ", and that did the job. 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
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

I think campaign.date_sent was a typo? 我认为campaign.date_sent是一个错字? It must be email.date_sent? 它必须是email.date_sent?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM