Mysql 在表复制操作中更新现有行和插入不存在行的最有效方法是什么?
我有两张桌子:Mysql 在表复制操作中更新现有行和插入不存在行的最有效方法是什么?,mysql,sql,Mysql,Sql,我有两张桌子: stock: pid name qty --- ---- --- 1 aaaa 2 2 bbbb 3 1 aaaa 5 3 cccc 1 2 bbbb 2 stock_total: pid name total_qty --- ---- --------- 我可以使用此查询从stock表中插入行,将总数量添加到stock\u total INSERT INTO stock_total (pid, name, total_qty) S
stock:
pid name qty
--- ---- ---
1 aaaa 2
2 bbbb 3
1 aaaa 5
3 cccc 1
2 bbbb 2
stock_total:
pid name total_qty
--- ---- ---------
我可以使用此查询从stock
表中插入行,将总数量添加到stock\u total
INSERT INTO stock_total (pid, name, total_qty)
SELECT pid, name, SUM(qty)
FROM stock
GROUP BY pid, name
问题是,我将通过cron作业运行上面的SQL。因此,在下一次执行时,SQL应该更新现有产品并插入不存在的产品
如果我循环选择结果,检查每一行是否存在于stock\u total
中,并进行插入或更新,那么效率将非常低
有没有更简单的方法来实现这一点?也许可以通过修改上面的SQL。谢谢。使用
重复密钥更新
:
INSERT INTO TABLENAME(col1, col2)
VALUES (@value, ‘yyy’)
ON DUPLICATE KEY UPDATE col1 = @value
这是更新的一部分:
UPDATE stock_total
SET total_qty = SUM(s.qty)
FROM stock_total st
INNER JOIN stock s
ON st.pid = s.pid
AND st.name = s.name
WHERE s.pid = st.pid
GROUP BY s.pid
这是插入的内容:
INSERT INTO stock_total
SELECT s.pid, s.name, SUM(s.qty)
FROM stock s
WHERE s.pid NOT IN (SELECT pid FROM stock_total)
GROUP BY s.pid, s.name
应该可以,试一试。为什么不从作业中调用存储过程
在块中的SP中捕获
重复键
异常和更新
。如果没有抛出异常,它将插入您正在搜索的内容。使用方法如下—
merge into stock_total s " +
"using (select ? pid, ? name, ? total_qty from dual) d " +
"on (s.pid = d.pid and s.name = d.name and s.total_qty = d.total_qty) " +
"when matched then " +
"update set s.pid= d.pid, s.name = d.name, s.total_qty = d.total_qty" +
"when not matched then " +
"insert (pid, name, total_qty) " +
"values(d.pid, d.name, d.total_qty)" ;
编辑(对于mySQL):
在谷歌搜索和试验了一些答案之后,我想出了这个解决方案。事实证明,MySQL支持在重复密钥更新时将
替换为…
和。所以我的问题是这样的:
REPLACE INTO stock_total
SELECT pid, name, SUM(qty)
FROM stock
GROUP by pid, name
或者
如果stock\u total
上存在一行,则第一次查询将删除该行,然后插入新行,
第二个查询将更新现有行
只有当表具有主键或唯一索引时,这两个查询才会起作用:
CREATE TABLE stock_total (
pid INT NOT NULL,
name VARCHAR(20) NOT NULL,
total_qty INT NOT NULL,
UNIQUE (pid, name)
);
文件:
哪种品牌的SQL可能重复?MySQL、SQL Server、Oracle等?不同的实现有不同的选项可供选择。我根据OP最初的问题回答了这个问题,然后他将它添加到mysql标签中。但这对甲骨文非常有效。对于mysql,请参阅我的编辑…我认为最终SQL将非常长,带有(HOLDLOCK)
的将我吓坏了:)。但是谢谢。我不是SP粉丝,但是回答很好。谢谢Majid,我不熟悉这种语法。我使用SQL Server,如果它能改进查询或答案,请随意编辑我的帖子,并提出您的建议。更新
不起作用,插入
错过了分组依据
。但我明白你的意思。谢谢,谢谢,我把插页修好了。更新时出现了什么错误?
INSERT INTO stock_total
SELECT pid, name, SUM(qty)
FROM stock
GROUP by pid, name
ON DUPLICATE KEY UPDATE total_qty=VALUES(total_qty)
CREATE TABLE stock_total (
pid INT NOT NULL,
name VARCHAR(20) NOT NULL,
total_qty INT NOT NULL,
UNIQUE (pid, name)
);