在 SQL 中,如何仅在 table 还没有行时才添加行?
In SQL, how can I add a row only if there isn’t any yet to a table?
示例:我有四个对象,其中 1 有三个 foobar(两个 "FOO" 和一个 "BAR"),2 有一个 "FOO" foobar(没有 "BAR" foobar这里 #1),3 有一个 "BAR" 和一个 "Good morning, John! :)" foobar,而 4 没有任何(这里 #2 没有 "BAR" foobar)。请注意类型列是字符串,不一定是唯一的,并且可能包含任意 crab es。
Table 'object':
| id | ...
+----+----
| 1 | ...
| 2 | ...
| 3 | ...
| 4 | ...
Table '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 = [=40= 的 foobar ], 添加到 foobar (next id, object.id, 'BAR', …)。命令后,foobar 中应该添加了以下内容 table:
| id | object_id | type | ...
+----+-----------+-------+----
| 7 | 2 | "BAR" | ... // adds missing #1
| 8 | 4 | "BAR" | ... // adds missing #2
我读过的关于插入缺失列的技术,例如INSERT IGNORE
和INSERT ... ON DUPLICATE KEY UPDATE
如果我理解正确的话在这里将不起作用,主要是因为'type'在这里不能是唯一的(由于数据限制)。
所以基本上我需要做的是加入一个不存在的行以便添加它,或者如此。我不知道。
我正在使用 MySQL 方言,如果有帮助的话。
使用一个不存在的:
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'
)
所以只要在 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 技巧是一个相当古老的技巧。
当您离开时加入 table。
例如:SELECT * FROM a LEFT JOIN b ON b.a_id = a.id
然后它将 return 来自 "a" 的所有行,即使该行无法链接到 "b".
然后,当 "b" 中的匹配记录丢失时,结果集中的 b.id 将为 NULL。
因此过滤 b.id IS NULL
return 没有匹配 "b".
的 "a"
示例:我有四个对象,其中 1 有三个 foobar(两个 "FOO" 和一个 "BAR"),2 有一个 "FOO" foobar(没有 "BAR" foobar这里 #1),3 有一个 "BAR" 和一个 "Good morning, John! :)" foobar,而 4 没有任何(这里 #2 没有 "BAR" foobar)。请注意类型列是字符串,不一定是唯一的,并且可能包含任意 crab es。
Table 'object':
| id | ...
+----+----
| 1 | ...
| 2 | ...
| 3 | ...
| 4 | ...
Table '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 = [=40= 的 foobar ], 添加到 foobar (next id, object.id, 'BAR', …)。命令后,foobar 中应该添加了以下内容 table:
| id | object_id | type | ...
+----+-----------+-------+----
| 7 | 2 | "BAR" | ... // adds missing #1
| 8 | 4 | "BAR" | ... // adds missing #2
我读过的关于插入缺失列的技术,例如INSERT IGNORE
和INSERT ... ON DUPLICATE KEY UPDATE
如果我理解正确的话在这里将不起作用,主要是因为'type'在这里不能是唯一的(由于数据限制)。
所以基本上我需要做的是加入一个不存在的行以便添加它,或者如此。我不知道。
我正在使用 MySQL 方言,如果有帮助的话。
使用一个不存在的:
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'
)
所以只要在 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 技巧是一个相当古老的技巧。
当您离开时加入 table。
例如:SELECT * FROM a LEFT JOIN b ON b.a_id = a.id
然后它将 return 来自 "a" 的所有行,即使该行无法链接到 "b".
然后,当 "b" 中的匹配记录丢失时,结果集中的 b.id 将为 NULL。
因此过滤 b.id IS NULL
return 没有匹配 "b".