har*_*ryg 64 mysql sql sql-insert
我想运行一组查询来将一些数据插入到SQL表中,但前提是满足某些条件的记录.该表有4个字段:( idprimary)fund_id,date和price
我在查询3个字段:fund_id,date和price.
所以我的查询会是这样的:
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'
);
Run Code Online (Sandbox Code Playgroud)
所以我只想在匹配fund_id和date不存在的记录时插入数据.如果以上是正确的,那么我觉得这是一种非常低效的方法,因为每次都必须运行一个额外的select语句.
有没有更好的方法来实现上述目标?
编辑:澄清既不是fund_id也不date是唯一的字段; 将存在共享相同fund_id或日期的记录,但没有记录应具有与另一个相同的fund_id和日期.
Tri*_*mon 58
这可能是实现此目的的简单解决方案:
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'));
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
看到这个小提琴.
har*_*ryg 40
虽然我最初标记为选择的答案是正确的,并达到了我所要求的更好的方法(其他人承认但没有进入).应在包含fund_id和的表上创建复合唯一索引date.
ALTER TABLE funds ADD UNIQUE KEY `fund_date` (`fund_id`, `date`);
Run Code Online (Sandbox Code Playgroud)
然后在插入记录时添加遇到冲突时的条件:
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
Run Code Online (Sandbox Code Playgroud)
这将为子查询提供更好的性能,并且表的结构更优越.它伴随着一个警告,即您的唯一键列中不能包含NULL值,因为它们仍然被MySQL视为值.
假设您无法修改DDL(以创建唯一约束)或仅限于能够编写DML,那么针对整个表检查值的过滤结果是否为null
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
Run Code Online (Sandbox Code Playgroud)