【问题标题】:MySQL: return field for which no related entries exist in another tableMySQL:返回另一个表中不存在相关条目的字段
【发布时间】:2011-06-10 09:28:52
【问题描述】:

首先,对不起标题,因为我不是以英语为母语的人,这很难说。换句话说,我想要实现的是:

  • 我正在尝试从表 virtual_domains 中获取所有域名,其中 virtual_aliases 表中没有以“postmaster@%”开头的相应条目。

所以如果我有两个域:

foo.org
example.org

他们的别名如下:

info@foo.org       => admin@foo.org
postmaster@foo.org => user1@foo.org
info@example.org   => admin@example.org

我希望查询仅返回域“foo.org”,因为“example.org”缺少邮递员别名。

这是表格布局:

mysql> show columns from virtual_aliases;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment | 
| domain_id   | int(11)      | NO   | MUL | NULL    |                | 
| source      | varchar(100) | NO   |     | NULL    |                | 
| destination | varchar(100) | NO   |     | NULL    |                | 
+-------------+--------------+------+-----+---------+----------------+

mysql> show columns from virtual_domains;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment | 
| name  | varchar(50) | NO   |     | NULL    |                | 
+-------+-------------+------+-----+---------+----------------+

我用 IF、CASE、LIKE 查询尝试了很多小时,但没有成功。我不需要最终的解决方案,也许只是带有一些解释的提示。谢谢!

【问题讨论】:

    标签: mysql subquery case


    【解决方案1】:
    select id,domain from virtual_domains 
    where id not in (select domain_id from virtual_aliases)
    

    【讨论】:

    • 它没有检查“postmaster@%”
    【解决方案2】:
    SELECT * FROM virtual_domains AS domains
    LEFT JOIN  virtual_aliases AS aliases
    ON domains.id = aliases.domain_id
    WHERE aliases.domain_id IS NULL
    

    LEFT JOIN 返回“左”表中的所有记录,即使它们在“右”表中没有对应的记录。这些记录将正确的表字段设置为 NULL。使用 WHERE 剥离所有其他内容。


    我想我第一次没有正确理解你。您在 aliases 中有多个针对单个域的条目,并且您只想显示别名表中没有以“postmaster”开头的条目的域?

    在这种情况下,您应该像这样使用NOT IN

    SELECT * FROM virtual_domains AS domains
    WHERE domains.id NOT IN (
        SELECT domain_id
        FROM virtual_aliases
        WHERE whatever_column LIKE "postmaster@%"
    )
    

    【讨论】:

    • 这非常有效。不知道这会那么“容易”实现。
    • 哎呀,我太快了:如果存在一些随机别名,此查询将失败(我想找到完全缺少“postmaster@”别名的域。但仍然感谢!
    • 我以前从未想过您的选择...在这种情况下,我比 NOT IN 子选择更喜欢它...但是,还有其他完全合法的子选择案例.
    • 我想我第一次误解了你。更新了我的答案
    • 太好了,这符合预期。非常感谢,也感谢所有其他人,您的意见也很有帮助。
    【解决方案3】:
    SELECT * FROM virtual_domains vd
    LEFT JOIN virtual_aliases va ON vd.id = va.domain_id
    AND va.destination NOT LIKE 'postmaster@%';
    

    【讨论】:

    • 谢谢,但这会返回与“postmaster@%”不匹配的所有内容。我想要一个缺少“postmaster@”别名的域列表(并且只有这个别名)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-11
    • 1970-01-01
    • 2020-10-08
    • 2022-01-23
    相关资源
    最近更新 更多