在 MySQL 数据库中,我有一个test
包含两列foo
和bar
. 我正在尝试编写一个单独的 SQL 语句,仅当这样的行不存在时才插入一行。我尝试了以下方法,但如果表为空,则它不起作用:
INSERT INTO test (foo, bar)
SELECT 'foo', 'bar'
FROM test
WHERE NOT EXISTS
(SELECT 1 FROM test WHERE foo = 'foo' AND bar = 'bar')
LIMIT 1;
测试表是空的,所以 Select 中不会有任何记录。所以使用Dual
table with Select
。
INSERT INTO test (foo, bar)
SELECT 'foo',
'bar'
From DUAL
WHERE NOT EXISTS (SELECT 1
FROM test
WHERE foo = 'foo'
AND bar = 'bar')
DUAL
纯粹是为了方便那些要求所有SELECT
语句都应该有FROM
可能还有其他子句的人。MySQL 可能会忽略这些子句。FROM DUAL
如果没有引用表,MySQL 不需要。
子句不必EXISTS
引用您从中选择的表,并且由于您仅在SELECT
for insert 语句中使用外部引用,您可以使用任何表进行选择,实际上您甚至不需要使用混凝土表,例如
INSERT INTO Test
SELECT 'foo', 'bar'
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM test WHERE foo = 'foo' AND bar = 'bar');
您是否尝试过类似的方法:
SELECT 'foo'
, 'bar'
WHERE 1 NOT IN (
SELECT CASE WHEN COUNT(*) < 1
THEN 0
ELSE 1
END
FROM test
WHERE foo = 'foo'
AND bar = 'bar'
)
请注意删除LIMIT 1
(我认为这LIMIT 1
没有伤害,但我认为它也没有帮助,因为该子句在子查询之外)。
请注意,上述内容经过测试,适用于空表。
此外,对于上述IN
内容,不是仅在返回非空集(或EXISTS
为EXISTS
的空集)时才返回 true NOT EXISTS
。
我认为您不能从要插入的同一个表中插入结果集并检查该行是否存在。
无论如何,如果没有,我想这是一个解决方法:
INSERT INTO test t1 (foo, bar)
ON DUPLICATE KEY update t1.foo=t2.foo;
编辑:在您的原始查询中,我认为您正在从 select 语句中插入。显然你只想插入一个给定的手动元组,所以我改变了我的建议。即使桌子是空的,它也应该工作。
可能使用REPLACE INTO
which 将替换现有记录或创建新记录(如果不存在)。取决于您的内容的具体情况,但这种方法是否可行。