在SQL中,如何仅在表中还没有行的情况下添加行



示例:我有四个对象,其中1有三个foobar(两个"FOO"和一个"BAR"(,2有一个"FO0"foobar(此处没有"BAR"foobar#1(,3有一个"BAR"和一个"早上好,John!:("foobar,4没有任何(此处没有"BAR"foobar#2(。请注意,type列是字符串,不一定是唯一的,并且可能包含任意的crab es。

表"对象":

| id | ...
+----+----
| 1  | ...
| 2  | ...
| 3  | ...
| 4  | ...

表"foobar":

| id | object_id | type                     | ...
+----+-----------+--------------------------+----
| 1  | 1         | "FOO"                    | ...
| 2  | 1         | "FOO"                    | ...
| 3  | 1         | "BAR"                    | ...
| 4  | 2         | "FOO"                    | ...
| 5  | 3         | "BAR"                    | ...
| 6  | 3         | "Good morning, John! :)" | ...

我想做的是一个命令:对于每个object.id,如果没有object_id=object.id和foobar.type='BAR'的foobar,则添加到foobar(下一个id,object.id、'BAR',…(。在命令之后,应该将以下内容添加到foobar表中:

| id | object_id | type  | ...
+----+-----------+-------+----
| 7  | 2         | "BAR" | ...  // adds missing #1
| 8  | 4         | "BAR" | ...  // adds missing #2

如果我理解正确的话,我读过的插入缺失列的技术(如INSERT IGNOREINSERT ... ON DUPLICATE KEY UPDATE(在这里不起作用,主要是因为"type"在这里不能是唯一的(由于数据限制(。

所以基本上,我需要做的是对一个不存在的行进行连接,以便添加它,或者说。我不知道。

我使用MySQL方言,如果这有帮助的话。

所以只需在foobar中找到没有"BAR"的对象
然后将它们插入foobar。

如果foobar.id是AUTO_INCREMENT的主键,则不需要插入id。

INSERT INTO foobar (object_id, type)
SELECT o.id, 'BAR' as Type
FROM object o
LEFT JOIN foobar f ON (f.object_id = o.id AND f.type = 'BAR')
WHERE f.id IS NULL

这里使用的SQL技巧是一个相当古老的技巧。

当你离开时加入一个表
例如:SELECT * FROM a LEFT JOIN b ON b.a_id = a.id
然后它将返回"a"中的所有行,即使该行无法链接到"b">
然后,当"b"中的匹配记录丢失时,结果集中的b.id将为NULL
因此,在b.id IS NULL上进行筛选会返回没有匹配"b"的"a"。

使用不存在的:

insert into mytable (object_id, type)
select object_id, 'BAR'
from mytable t1
where type = 'FOO'
and not exists 
(
select 1 
from mytable t2 
where t1.object_id = t2.object_id 
and type = 'BAR'
)

最新更新