4

我试图更好地理解“不在”如何与 MySQL 中的 WHERE 一起工作。

例如:

SELECT * FROM current_mailing_list 
WHERE address1 NOT IN
    (select address1 from old_mailing_list) AND
    city not in (select city from old_mailing_list);

在上面的示例中,查询的目的是列出新的邮寄地址。address1是街道地址,例如1234 N. Main St. 当1234 N. Main St发生在多个城市时,问题就会发生,这可能会发生。所以我决定添加city它以使其更加独特。

我的问题是,这是否符合我的预期?old_mailing_list 意思是,它应该找到那些在AND中不存在的街道地址(address1),然后确保它们具有不同的city.

我已经这样做了,只是使用地址1:

SELECT * FROM current_mailing_list 
WHERE address1 NOT IN 
    (select address1 from old_mailing_list);

它产生了一个更大的列表(大约是大小的 10 倍)。所以我想补充city一下。还是我的逻辑完全错误,需要另一种方法?

4

3 回答 3

6

您当前的查询将不会返回他们的“address1”或“city”根本出现在旧邮件列表中的新地址。我认为您想选择它们不会同时出现的城市,如下所示:

SELECT *
FROM current_mailing_list c
WHERE NOT EXISTS
(
    SELECT 1
    FROM old_mailing_list
    WHERE
        address1 = c.address1
        AND city = c.city
)

毫不夸张的说; 从当前邮件列表中选择旧邮件列表中没有具有相同城市和地址的记录的所有内容1。

于 2013-04-18T19:43:47.543 回答
3

要使用NOT IN,您需要将 city 和 address 组合在同一个子句中,因为 MySQL 支持此方法(其他 RDBMS 不支持此方法)。正如其他人指出的那样,单独使用两者不会获得所需的结果。

如果你想使用,试试这个NOT IN

SELECT * 
FROM current_mailing_list 
WHERE (address1,city) NOT IN  
   (select address1, city from old_mailing_list);

示例 SQL Fiddle 演示

我个人更喜欢使用 aLEFT JOIN并检查 NULL:

SELECT c.* 
FROM current_mailing_list c
    LEFT JOIN old_mailing_list o ON c.address1 = o.address1 AND c.city = o.city
WHERE o.address1 IS NULL
于 2013-04-18T19:47:00.753 回答
1

如果 1234 N. Main St. 是旧邮件列表中的城市和新邮件列表中的城市的地址,则您的查询将排除这两个地址。您的查询与它所说的完全一样:您将获得街道地址和城市不在旧邮件列表中的地址。如果一地址出现在旧邮件列表中,则不会检索该地址。

于 2013-04-18T19:42:42.117 回答