在 MySQL 中进行重复密钥更新
put on duplicate key update in MySQL
假设我有 2 tables
CREATE TABLE shipping(id int(10) NOT NULL PRIMARY KEY AUTO_INCREMENT, origin INT(10),
order_id int(10), createdAt date NOT NULL, product_id varchar(100) NOT NULL,
amount decimal(10,0));
CREATE TABLE reprint (id int(10) NOT NULL PRIMARY KEY AUTO_INCREMENT,
product_id int(50), reprintAt varchar(255), status tinyint(4));
INSERT INTO shipping (origin, order_id, createdAt, product_id, amount)
VALUES (1, 11, NOW(), 234, 2000),
(1, 11, NOW(), 235, 3000),
(1, 11, NOW(), 236, 4000),
(2, 12, NOW(), 236, 3000),
(2, 12, NOW(), 235, 2100),
(3, 13, NOW(), 236, 2200),
(3, 13, NOW(), 239, 3400),
(4, 14, NOW(), 237, 2300),
(4, 14, NOW(), 233, 4000);
INSERT INTO reprint (product_id, reprintAt, status)
VALUES (234, NOW() + INTERVAL 1 DAY, 1),
(235, NOW() + INTERVAL 2 DAY, 1),
(236, NOW(), 1),
(237, NOW(), 1),
(238, NOW(), 1),
(239, NOW(), 1),
(240, NOW(), 1),
(233, NOW(), 1);
table 运费
id
origin
order_id
createdAt
product_id
amount
1
1
11
2020-12-22
234
2000
2
1
11
2020-12-22
235
3000
3
1
11
2020-12-22
236
4000
4
2
12
2020-12-22
236
3000
5
2
12
2020-12-22
235
2100
6
3
13
2020-12-22
236
2200
7
3
13
2020-12-22
239
3400
8
4
14
2020-12-22
237
2300
9
4
14
2020-12-22
233
4000
table转载
id
product_id
reprintAt
status
1
234
2020-12-23 10:38:02
1
2
235
2020-12-24 10:38:02
1
3
236
2020-12-22 10:38:02
1
4
237
2020-12-22 10:38:02
1
5
238
2020-12-22 10:38:02
1
6
239
2020-12-22 10:38:02
1
7
240
2020-12-22 10:38:02
1
8
233
2020-12-22 10:38:02
1
所以有2个table,同一个product_id。如果转载和发货的product_id个数不一样,则将一些包含缺失product_id的记录放入发货。在这种情况下,product_Id '238' 和 '240' 不包含在 table 运费中,因此我必须在运费中插入包含 product_id '238' 和 '240' 的新记录table.
对于这些要求,预期的结果应该是这样的(请查看 product_id 238 和 240 table)
id
origin
order_id
createdAt
product_id
amount
1
1
11
2020-12-22
234
2000
2
1
11
2020-12-22
235
3000
3
1
11
2020-12-22
236
4000
4
2
12
2020-12-22
236
3000
5
2
12
2020-12-22
235
2100
6
3
13
2020-12-22
236
2200
7
3
13
2020-12-22
239
3400
8
4
14
2020-12-22
237
2300
9
4
14
2020-12-22
233
4000
10
5
16
2020-12-22
238
4000
11
7
16
2020-12-22
240
4000
我正在尝试这个查询
DECLARE test_1 INT DEFAULT 0;
DECLARE test_2 INT DEFAULT 0;
SELECT count(distinct product_id) INTO test_1 FROM shipping;
SELECT count(distinct product_id) INTO test_2 FROM reprint;
IF test_1 != test_2 THEN
INSERT INTO shipping (id, origin, order_id, createdAt, product_id, amount)
SELECT LAST_INSERT_ID(), reprint.id, 16, reprint.reprintAt, reprint.product_id, 4000
FROM
reprint
UNION
SELECT * FROM shipping
ON duplicate key update product_id = values(product_id);
但是它说
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DECLARE test_1 INT DEFAULT 0;
DECLARE test_2 INT DEFAULT 0;
SELECT count(distin' at line 1
这是fiddlehttps://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=c489fdb3c6c07bb597bf23928ab97397
如果我没看错的话,你可以直接用not exists
:
insert into shipping (origin, order_id, createdat, product_id, amount)
select id, 16, reprintat, product_id, 4000
from reprint r
where not exists (select 1 from shipping s where s.product_id = r.product_id)
这会为转载中的每一行创建一个新的运输行,其产品在目标中尚不存在,数量和订单 ID 不变。
我认为 on duplicate key
在这种情况下没有意义,因为产品不是唯一的列。
我认为您的问题可以通过简单的 SQL 查询使用 NOT EXISTS
语句解决:
INSERT INTO shipping (origin, order_id, createdAt, product_id, amount)
SELECT reprint.id, 16, reprint.reprintAt, reprint.product_id, 4000
FROM reprint
WHERE NOT EXISTS (
SELECT product_id FROM shipping WHERE shipping.product_id = reprint.product_id
);
这里是fiddle
假设我有 2 tables
CREATE TABLE shipping(id int(10) NOT NULL PRIMARY KEY AUTO_INCREMENT, origin INT(10),
order_id int(10), createdAt date NOT NULL, product_id varchar(100) NOT NULL,
amount decimal(10,0));
CREATE TABLE reprint (id int(10) NOT NULL PRIMARY KEY AUTO_INCREMENT,
product_id int(50), reprintAt varchar(255), status tinyint(4));
INSERT INTO shipping (origin, order_id, createdAt, product_id, amount)
VALUES (1, 11, NOW(), 234, 2000),
(1, 11, NOW(), 235, 3000),
(1, 11, NOW(), 236, 4000),
(2, 12, NOW(), 236, 3000),
(2, 12, NOW(), 235, 2100),
(3, 13, NOW(), 236, 2200),
(3, 13, NOW(), 239, 3400),
(4, 14, NOW(), 237, 2300),
(4, 14, NOW(), 233, 4000);
INSERT INTO reprint (product_id, reprintAt, status)
VALUES (234, NOW() + INTERVAL 1 DAY, 1),
(235, NOW() + INTERVAL 2 DAY, 1),
(236, NOW(), 1),
(237, NOW(), 1),
(238, NOW(), 1),
(239, NOW(), 1),
(240, NOW(), 1),
(233, NOW(), 1);
table 运费
id | origin | order_id | createdAt | product_id | amount |
---|---|---|---|---|---|
1 | 1 | 11 | 2020-12-22 | 234 | 2000 |
2 | 1 | 11 | 2020-12-22 | 235 | 3000 |
3 | 1 | 11 | 2020-12-22 | 236 | 4000 |
4 | 2 | 12 | 2020-12-22 | 236 | 3000 |
5 | 2 | 12 | 2020-12-22 | 235 | 2100 |
6 | 3 | 13 | 2020-12-22 | 236 | 2200 |
7 | 3 | 13 | 2020-12-22 | 239 | 3400 |
8 | 4 | 14 | 2020-12-22 | 237 | 2300 |
9 | 4 | 14 | 2020-12-22 | 233 | 4000 |
table转载
id | product_id | reprintAt | status |
---|---|---|---|
1 | 234 | 2020-12-23 10:38:02 | 1 |
2 | 235 | 2020-12-24 10:38:02 | 1 |
3 | 236 | 2020-12-22 10:38:02 | 1 |
4 | 237 | 2020-12-22 10:38:02 | 1 |
5 | 238 | 2020-12-22 10:38:02 | 1 |
6 | 239 | 2020-12-22 10:38:02 | 1 |
7 | 240 | 2020-12-22 10:38:02 | 1 |
8 | 233 | 2020-12-22 10:38:02 | 1 |
所以有2个table,同一个product_id。如果转载和发货的product_id个数不一样,则将一些包含缺失product_id的记录放入发货。在这种情况下,product_Id '238' 和 '240' 不包含在 table 运费中,因此我必须在运费中插入包含 product_id '238' 和 '240' 的新记录table.
对于这些要求,预期的结果应该是这样的(请查看 product_id 238 和 240 table)
id | origin | order_id | createdAt | product_id | amount |
---|---|---|---|---|---|
1 | 1 | 11 | 2020-12-22 | 234 | 2000 |
2 | 1 | 11 | 2020-12-22 | 235 | 3000 |
3 | 1 | 11 | 2020-12-22 | 236 | 4000 |
4 | 2 | 12 | 2020-12-22 | 236 | 3000 |
5 | 2 | 12 | 2020-12-22 | 235 | 2100 |
6 | 3 | 13 | 2020-12-22 | 236 | 2200 |
7 | 3 | 13 | 2020-12-22 | 239 | 3400 |
8 | 4 | 14 | 2020-12-22 | 237 | 2300 |
9 | 4 | 14 | 2020-12-22 | 233 | 4000 |
10 | 5 | 16 | 2020-12-22 | 238 | 4000 |
11 | 7 | 16 | 2020-12-22 | 240 | 4000 |
我正在尝试这个查询
DECLARE test_1 INT DEFAULT 0;
DECLARE test_2 INT DEFAULT 0;
SELECT count(distinct product_id) INTO test_1 FROM shipping;
SELECT count(distinct product_id) INTO test_2 FROM reprint;
IF test_1 != test_2 THEN
INSERT INTO shipping (id, origin, order_id, createdAt, product_id, amount)
SELECT LAST_INSERT_ID(), reprint.id, 16, reprint.reprintAt, reprint.product_id, 4000
FROM
reprint
UNION
SELECT * FROM shipping
ON duplicate key update product_id = values(product_id);
但是它说
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DECLARE test_1 INT DEFAULT 0;
DECLARE test_2 INT DEFAULT 0;
SELECT count(distin' at line 1
这是fiddlehttps://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=c489fdb3c6c07bb597bf23928ab97397
如果我没看错的话,你可以直接用not exists
:
insert into shipping (origin, order_id, createdat, product_id, amount)
select id, 16, reprintat, product_id, 4000
from reprint r
where not exists (select 1 from shipping s where s.product_id = r.product_id)
这会为转载中的每一行创建一个新的运输行,其产品在目标中尚不存在,数量和订单 ID 不变。
我认为 on duplicate key
在这种情况下没有意义,因为产品不是唯一的列。
我认为您的问题可以通过简单的 SQL 查询使用 NOT EXISTS
语句解决:
INSERT INTO shipping (origin, order_id, createdAt, product_id, amount)
SELECT reprint.id, 16, reprint.reprintAt, reprint.product_id, 4000
FROM reprint
WHERE NOT EXISTS (
SELECT product_id FROM shipping WHERE shipping.product_id = reprint.product_id
);
这里是fiddle