SQL查询重复记录
问题描述:
我有两张表。 我们称它们为table_A和table_B。SQL查询重复记录
Table_B包含table_A的ForeignKey。
Table_A
ID Name
1 A
2 B
3 C
Table_B
ID table_a_fk
1 2
2 3
现在我想从table_a中获取所有名称如果table_b不包含table_a中记录的ID。
我与此查询试了一下:
SELECT a.name
FROM table_a a, table_b b
WHERE a.id != b.table_a_fk
与此查询我得到正确的结果我刚得到这个结果像5倍,我不知道为什么。
希望有人能解释我。
答
你的查询创建你的两个表A
和B
之间的cartesian product。这是笛卡尔产品,可以产生这些重复值。与NOT IN
相反,你想用NOT EXISTS
SELECT a.name
FROM table_a a
WHERE NOT EXISTS (
SELECT *
FROM table_b b
WHERE a.id = b.table_a_fk
)
表达的另一种方法是使用一个anti-join,这是最常见的SQL编写的反连接(only if table_b.table_a_fk
is NOT NULL
):
SELECT a.name
FROM table_a a
WHERE a.id NOT IN (
SELECT b.table_a_fk
FROM table_b b
)
另一种不常见表达反连接的方法:
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
答
使用不同
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)
我对使用DISTINCT修复语义错误的查询的建议感到有点惊讶。另外,第二个查询也是错误的。 –
@Lukas,虽然它可能看起来应该是唯一的,但在问题中没有什么可以支持'name'字段在数据集中是唯一的。因此,为避免输出中出现重复名称,必须使用不同的名称。你是正确的,第一个查询是丑陋的,但很难说任何有效的东西都是*错误*。这是在我的回答中,因为这是他在问题中提出的形式,所以基于他可以理解的内容的解决方案可能更有可能得到解决。 –
让'table_a'包含'(1,A)'和'table_b'为空。你的第一个查询将返回任何内容而不是'A'。这是不对的。您的第二个查询对于OP建议的数据集是错误的。 –