我希望在具有以下字段的MySQL表上UPSERT
(UPDATE
,如果存在,否则插入):
CREATE TABLE item (
uid int(11) NOT NULL AUTO_INCREMENT,
timestamp int(11) NOT NULL DEFAULT '0',
category1 int(11) NOT NULL DEFAULT '0',
category2 int(11) NOT NULL DEFAULT '0',
counter int(11) NOT NULL DEFAULT '1',
PRIMARY KEY (`uid`)
)
此表已投入使用,(timestamp,category1,category2)
的组合适用于INSERT
唯一,但不适用于整个表格内容。这就是为什么我不能使用“ ON DUPLICATE KEY ”功能的原因。
有关UNIQUE问题的说明:
如果category1 = 9,则这是我的插入,(timestamp,category1,category2)
是唯一的。但该表正在高效使用,如果category1 = 1,2,则(timestamp,category1,category2)
不是唯一的。
据我所知,我无法添加UNIQUE
密钥,因为它会产生类别1 + 2的问题。
我需要的是这样的事情:
IF (timestamp,category1,category2) exists
counter=existingCount + newCount
ELSE
insert new record
我使用PHP和MySQL,因此两种语言的任何组合都可以。
我已经尝试过但需要花费太多时间的是:
SELECT
语句,然后是UPDATE
或INSERT
INSERT
然后UPDATE
和DELETE
重复行感谢我现在创建的这个存储过程的答案,语法没问题,但程序无效:
DROP PROCEDURE IF EXISTS myUpsert;
DELIMITER |
CREATE PROCEDURE myUpsert (IN v_timestamp INT, IN v_category1 INT, IN v_category2 INT, IN v_counter INT)
BEGIN
DECLARE existingCounter INT;
SELECT COUNT(counter) AS existingCounter from item
WHERE timestamp =v_timestamp AND category1=v_category1 AND category2=v_category2;
IF existingCounter=0 THEN
INSERT INTO item (timestamp,category1,category2,counter)
VALUES (v_timestamp,v_category1,v_category2,v_counter);
ELSE
UPDATE item SET count=v_counter+existingCounter
WHERE timestamp=v_timestamp AND category1=v_category1 AND category2=v_category2;
END IF;
END
|
DELIMITER ;
答案 0 :(得分:1)
我建议为这三列添加唯一索引:
ALTER TABLE项ADD UNIQUE(timestamp,category1,category2)
答案 1 :(得分:0)
DROP PROCEDURE IF EXISTS myUpsert;
DELIMITER |
CREATE PROCEDURE myUpsert (IN v_timestamp INT, IN v_category1 INT, IN v_category2 INT, IN v_counter INT)
BEGIN
DECLARE existingCounter INT;
SET existingCounter = (SELECT COUNT(counter) from item
WHERE timestamp =v_timestamp AND category1=v_category1 AND category2=v_category2);
IF existingCounter=0 THEN
INSERT INTO item (timestamp,category1,category2,counter)
VALUES (v_timestamp,v_category1,v_category2,v_counter);
ELSE
UPDATE item SET count=v_counter+existingCounter
WHERE timestamp=v_timestamp AND category1=v_category1 AND category2=v_category2;
END IF;
END
|
DELIMITER ;