【问题标题】:How do I create a join which says a field is not equal to X?如何创建一个字段不等于 X 的连接?
【发布时间】:2010-07-20 20:09:41
【问题描述】:

我有以下数据库表,其中包含有关人员、疾病和药物的信息:

PERSON_T              DISEASE_T               DRUG_T
=========             ==========              ========
PERSON_ID             DISEASE_ID              DRUG_ID
GENDER                PERSON_ID               PERSON_ID
NAME                  DISEASE_START_DATE      DRUG_START_DATE
                      DISEASE_END_DATE        DRUG_END_DATE

我想编写一个查询来查找所有患有 disease_id 52 但未服用药物 34 的人。我该怎么做?我在 MySql 中尝试了以下操作:

SELECT p.person_id, p.gender, p.name, disease_id, drug_id 
   FROM person_t as p 
   INNER JOIN disease_t on disease_t.person_id = p.person_id 
   RIGHT OUTER JOIN drug_t on drug_t.person_id = p.person_id 
   WHERE disease_id= 52 AND drug_id != 34;

这为我提供了一个人没有服用 drug_id 34 的所有记录,而不是没有服用 drug_id 34 的人。我将如何编写我想要的查询?

【问题讨论】:

    标签: sql database join


    【解决方案1】:

    您可以使用 NOT IN:

    SELECT p.person_id, p.gender, p.name, disease_id
    FROM person_t as p 
    INNER JOIN disease_t d on disease_t.person_id = p.person_id 
    WHERE disease_id = 52
    AND p.person_id NOT IN (SELECT person_id IN drug_t WHERE drug_id = 34)
    

    【讨论】:

      【解决方案2】:

      对于那些不想使用子查询的人:

         SELECT p.person_id, p.gender, p.name, disease_id
           FROM PERSON_T p 
           JOIN DISEASE_T d ON d.person_id = p.person_id 
      LEFT JOIN DRUG_T dt ON dt.person_id = p.person_id
                         AND dt.drug_id = 34
          WHERE disease_id = 52
            AND dt.person_id IS NULL
      
      【解决方案3】:

      取决于优化器,NOT EXISTS 可能比 NOT IN 更有效。两种方法都试一下,看看哪一种效果最好。

      SELECT p.person_id, p.gender, p.name, disease_id, drug_id 
         FROM person_t as p 
         INNER JOIN disease_t on disease_t.person_id = p.person_id 
         WHERE disease_id= 52 AND NOT EXISTS (
             SELECT * from drug_T WHERE person_id = person_t.person_id AND drug_id = 34)
      

      【讨论】:

      • +1 表示不存在 - 这几乎总是会产生明显更好的性能。
      • 在 SQL Server 中使用 NOT EXISTS 是可以的,但他似乎在使用 MySQL。根据这篇文章:explainextended.com/2009/09/18/…“这就是为什么在 MySQL 中搜索缺失值的最佳方法是使用 LEFT JOIN / IS NULL 或 NOT IN 而不是 NOT EXISTS。”我想无论如何尝试它都没有坏处......但可能会更慢。
      • 有趣,所以 MySQL 优化器以另一种方式工作。 MySQL 有时是一种奇怪的动物。感谢您的链接。
      • 为了将来的可维护性目的,我通常更喜欢使用“不存在”:很明显你在做什么。但是当我比较性能时,我通常发现“left join / is null”要快一些。
      猜你喜欢
      • 1970-01-01
      • 2019-06-16
      • 1970-01-01
      • 1970-01-01
      • 2013-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-16
      相关资源
      最近更新 更多