SQL查询复制记录

SQL查询复制记录,sql,oracle,plsql,Sql,Oracle,Plsql,我有两张桌子。 我们把他们叫做A桌和B桌 表_B包含表_A的外键 Table_A ID Name 1 A 2 B 3 C Table_B ID table_a_fk 1 2 2 3 现在,如果表_b不包含表_a中记录的ID,我想从表_a中获取所有名称 我已经尝试过这个查询: SELECT a.name FROM table_a a, table_b b WHER

我有两张桌子。 我们把他们叫做A桌和B桌

表_B包含表_A的外键

Table_A

ID         Name
1          A
2          B
3          C

Table_B



ID         table_a_fk
1          2 
2          3
现在,如果表_b不包含表_a中记录的ID,我想从表_a中获取所有名称

我已经尝试过这个查询:

SELECT a.name
FROM table_a a, table_b b
WHERE a.id != b.table_a_fk
通过这个查询,我得到了正确的结果,我只得到了5次这个结果,我不知道为什么

希望有人能给我解释一下。

使用不同的

SELECT distinct  a.name
FROM table_a a, table_b b
WHERE a.id != b.table_a_fk
或者更好的是

Select distinct name
from tableA a
Where not exists (Select * from tableB 
                  Where table_a_fk = a.id)
您的查询在两个表
a
B
之间创建了一个。正是笛卡尔积生成了这些重复值。相反,您希望使用,这通常是使用
notexists
SQL编写的

SELECT a.name
FROM table_a a
WHERE NOT EXISTS (
  SELECT *
  FROM table_b b
  WHERE a.id = b.table_a_fk
)
不在
()中表示反连接的另一种方法:

另一种不太常见的表示反连接的方式:

SELECT a.name
FROM table_a a
LEFT OUTER JOIN table_b b ON a.id = b.table_a_fk
WHERE b.id IS NULL

使用
DISTINCT
修复语义错误的查询的建议让我有点惊讶。。。另外,第二个查询也是错误的。@Lukas,尽管看起来它应该是唯一的,但问题中没有任何东西支持
name
字段在数据集中是唯一的。因此,为了避免输出中出现重复的名称,必须使用distinct。第一个查询很难看,这是正确的,但很难说任何有效的查询都是错误的。这是在我的回答中,因为这是op在他的问题中提出的形式,因此一个建立在他{可以说]已经熟悉的基础上的解决方案可能更容易理解这一点
,和
表b
为空。您的第一个查询将不返回任何内容,而不是
A
。这是错误的。您的第二个查询对于OP建议的数据集是错误的。@Lukas,OP的问题明确指出:“通过此查询,我得到了正确的结果,我只得到了大约5次的结果,我不知道为什么。”。如果这是真的,(我没有理由怀疑这句话),那么添加distinct将消除重复。而且您无法知道OPs数据库中的数据。查尔斯:)是的,您的查询1适用于OP的数据。但是:请查看OP的文字“现在,如果表b不包含表a中记录的ID,我想从表a中获取所有名称。”OP需要反联接。您的任何建议都没有实现反联接。使用其他数据集,您的查询1将不起作用。在查询2中,将
替换为
=
,这将是正确的
SELECT a.name
FROM table_a a
LEFT OUTER JOIN table_b b ON a.id = b.table_a_fk
WHERE b.id IS NULL