SQL仅当logging不存在时插入到表中

我想要运行一组查询来将一些数据插入到一个SQL表中,但只有满足某些条件的logging才会被满足。 该表有4个字段: id (主), fund_iddateprice

我在查询中有3个字段: fund_iddateprice

所以我的查询会像这样:

 INSERT INTO funds (fund_id, date, price) VALUES (23, '2013-02-12', 22.43) WHERE NOT EXISTS ( SELECT * FROM funds WHERE fund_id = 23 AND date = '2013-02-12' ); 

所以我只想插入数据,如果匹配的fund_iddate的logging不存在。 如果以上是正确的,那么我认为这是一个非常低效的方法,因为每次都必须运行额外的select语句。

有没有更好的方法来达到上述目的?

编辑:澄清既不fund_id也不是唯一的领域; 共享相同的fund_id或date的logging将存在,但是没有logging应该具有与另一个相同的fund_id和date。

这可能是一个简单的解决scheme来实现这一点:

 INSERT INTO funds (ID, date, price) SELECT 23, DATE('2013-02-12'), 22.5 FROM dual WHERE NOT EXISTS (SELECT 1 FROM funds WHERE ID = 23 AND date = DATE('2013-02-12')); 

ps或者(如果ID是主键):

  INSERT INTO funds (ID, date, price) VALUES (23, DATE('2013-02-12'), 22.5) ON DUPLICATE KEY UPDATE ID = 23; -- or whatever you need 

看这小提琴 。

尽pipe我最初select的答案是正确的,并且达到了我所要求的更好的方式(其他人承认但没有进入)。 应该在由fund_iddate组成的表上创build一个复合唯一索引。

 ALTER TABLE funds ADD UNIQUE KEY `fund_date` (`fund_id`, `date`); 

然后在插入logging时添加遇到冲突时的条件:

 INSERT INTO funds (`fund_id`, `date`, `price`) VALUES (23, DATE('2013-02-12'), 22.5) ON DUPLICATE KEY UPDATE `price` = `price`; --this keeps the price what it was (no change to the table) or: INSERT INTO funds (`fund_id`, `date`, `price`) VALUES (23, DATE('2013-02-12'), 22.5) ON DUPLICATE KEY UPDATE `price` = 22.5; --this updates the price to the new value 

这将为子查询提供更好的性能,并且表的结构是优越的。 它带有警告,你不能在你的唯一键列中有NULL值,因为它们仍然被MySQL视为值。

假设你不能修改DDL(创build一个唯一的约束),或者只能写DML,那么检查你的值对整个表的过滤结果为空

小提琴

 insert into funds (ID, date, price) select T.* from (select 23 ID, '2013-02-12' date, 22.43 price) T left join funds on funds.ID = T.ID and funds.date = T.date where funds.ID is null