0

我有 2 张桌子:

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_total

INSERT INTO stock_total (pid, name, total_qty)
SELECT pid, name, SUM(qty) 
FROM stock
GROUP BY pid, name

问题是,我将通过 cron 作业运行上面的 SQL。所以在下一次执行时,SQL 应该更新现有产品并插入不存在的产品。

如果我遍历 SELECT 结果,检查每一行是否存在stock_total并执行 INSERT 或 UPDATE,这将是非常低效的。

有没有更简单的方法来实现这一点?也许通过修改上面的SQL。谢谢。

4

5 回答 5

1

使用DUPLICATE KEY UPDATE

INSERT INTO TABLENAME(col1, col2)
VALUES (@value, ‘yyy’)
ON DUPLICATE KEY UPDATE col1 = @value
于 2012-05-24T08:22:02.080 回答
1

这是为了更新:

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

应该没问题,试试看。

于 2012-05-24T08:23:33.110 回答
0

为什么不从工作中调用存储过程?

在块中的 SP 中捕获DUPLICATE KEY异常并UPDATE. 如果没有EXCEPTION抛出它会INSERT

于 2012-05-24T08:24:08.977 回答
0

merge是你正在寻找的东西。按如下方式使用它 -

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):

MERGE INTO table_name WITH (HOLDLOCK) USING table_name ON (condition)
WHEN MATCHED THEN UPDATE SET column1 = value1 [, column2 = value2 ...]
WHEN NOT MATCHED THEN INSERT (column1 [, column2 ...]) VALUES (value1 [, value2 ...])
于 2012-05-24T08:25:20.577 回答
0

经过一番谷歌搜索并尝试了这里的答案,我想出了这个解决方案。事实证明,MySQL 支持REPLACE INTO......ON DUPLICATE KEY UPDATE. 所以我的查询是这样的:

REPLACE INTO stock_total
SELECT pid, name, SUM(qty)
FROM stock
GROUP by pid, name

或者,

INSERT INTO stock_total
SELECT pid, name, SUM(qty)
FROM stock
GROUP by pid, name
ON DUPLICATE KEY UPDATE total_qty=VALUES(total_qty)

如果在 上存在一行stock_total,第一个查询将 DELETE 然后 INSERT 新行,第二个查询将 UPDATE 现有行。

只有当表具有主键或唯一索引时,这两个查询才会起作用:

CREATE TABLE stock_total (
    pid         INT         NOT NULL,
    name        VARCHAR(20) NOT NULL,
    total_qty   INT         NOT NULL,

    UNIQUE (pid, name)
);

文档:

于 2012-05-24T12:16:02.050 回答