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 であり、2 番目のクエリにないことを意味します。したがって、私の最初のクエリは 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 に答える
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 に答える