SQL:选择另一个表中没有复合主键的条目

Posted

技术标签:

【中文标题】SQL:选择另一个表中没有复合主键的条目【英文标题】:SQL: Select entries which don't have composite primary key in another table 【发布时间】:2016-06-30 22:36:06 【问题描述】:

所以我有两个表,它们都有一个由两列组成的复合主键。我想在第一个表中找到第二个表中不存在的条目,始终牢记我的主键是复合的。

我知道我必须使用NOT IN,但我不确定如何使它与两个主键一起使用。基本上我想要这样的东西:

SELECT * FROM table1 
WHERE id NOT IN (SELECT id FROM table2)

id 虽然是由两列组成的复合主键,id1id2。 有什么想法可以解决这个问题吗?

编辑:考虑到NOT IN 的危险,我将尝试更好地描述我需要什么。 除了选择不在第二个表中的条目外,还需要在同一个查询中完成两个操作:

选择小于 5 的列,我认为可以使用 AND t1.column <5 轻松完成 内部连接 ​​table1id1 上的第三个表,因为我需要该表中的一列。

【问题讨论】:

@GordonLinoff 你能解释一下原因吗? 【参考方案1】:

您可以将行构造函数与NOT IN 一起使用:

SELECT *
FROM table1 
WHERE (id1, id2) NOT IN (SELECT id1, id2 FROM table2);

【讨论】:

【参考方案2】:

not in 似乎会使事情变得过于复杂 - 而且,根据 Drew 的评论,如果括号内的任何内容可以是 null,则可能非常危险和/或令人愤怒。

这似乎是教科书对outer join 的使用。在键的列上使用left [outer] join,如果在连接后发现它们(或右侧表中的任何其他单个非nullable 列)为null,则意味着没有匹配的记录右侧表格中的那个复合键。

select *
from
    t1
    inner join t3 on
        t1.whatever = t3.whatever
    left join t2 on
        t1.id1 = t2.id1 and
        t1.id2 = t2.id2
where
    t1.some_column < 5 and -- 'normal' where criteria
    t2.id1 is null;         -- no match for key in t2

【讨论】:

问题是我已经必须执行 INNER JOIN,所以在同一个查询中执行 LEFT JOIN 对我来说太复杂了。您的解决方案可能是正确的,感谢您的洞察力。 @user3484582 那么在您的问题中包含其他先决条件是个好主意。随时更新它,我会看看我是否可以根据可用的改进信息更具体地回答它。 如果人们到处使用not in 而没有提到the dangers(毕竟,这里的人都是新手),那么糟糕。后来,由于它是他们方便的工具箱的一部分,他们花费了无数小时来调试他们的代码,甚至不知道有问题。 我看到了危险。我编辑了我的 OP 来描述我在查询中需要什么。我真的不知道如何结合 INNER JOIN 和 LEFT JOIN。感谢您迄今为止的帮助。 @user3484582 我已经编辑了我的答案。 t1 上的额外 inner join 到第三张表不应该出现问题,只要您对 left joint2 的含义感到满意:inner join 从概念上过滤掉输入的内容进入left join。至于您在t1 中提到的附加标准,您可以将其添加到where 子句中是正确的。一旦你能够尝试这些以及它们是否产生正确的结果,请告诉我!

以上是关于SQL:选择另一个表中没有复合主键的条目的主要内容,如果未能解决你的问题,请参考以下文章

休眠仅保存具有复合主键中的父外键的子表条目

用于更改表添加复合主键的批量 SQL 语句

如何识别任何 Mysql 数据库表中的复合主键?

mysql外键仅引用复合主键的一部分

WHERE col1,col2 IN (...) [使用复合主键的 SQL 子查询]

级联保存具有外键的实体对象作为复合主键的一部分