我在 MySql 上的 INSERT ~ SELECT ~ ON DUPLICATE KEY 查询有什么问题?

What's wrong with my INSERT ~ SELECT ~ ON DUPLICATE KEY query on MySql?


大家好

我做了一个使用 INSERT .. UPDATE .. ON DUPLICATE 的查询。

但是我做的查询没有工作,因为语法问题,我不知道为什么!

这是我尝试做的事情。

我尝试做的是给每个账号三个'magic_potion'

首先,我制作了两个表格。

CREATE TABLE account(
    account_no INT AUTO_INCREMENT,
    account_id VARCHAR(32) NOT NULL,
    account_pw VARCHAR(40) NOT NULL,
    PRIMARY KEY(account_no)
);

CREATE TABLE item(
    item_no INT AUTO_INCREMENT,
    account_id VARCHAR(32) NOT NULL,
    item_name VARCHAR(32) NOT NULL,
    item_count SMALLINT NOT NULL,
    item_status SMALLINT NOT NULL,
    PRIMARY KEY(item_no)
);

其次,我放了三个账号进行测试。

INSERT INTO account (account_id, account_pw) VALUES ('James', MD5('James')), ('Andy', MD5('James')), ('Angela', MD5('James'));

第三,我给了每个账号magic_potion

INSERT
INTO    item
SELECT  NULL, A.account_id, item_name, item_count, item_status
FROM    account A
        CROSS JOIN (SELECT 'magic_potion' AS item_name, 3 AS item_count, 1 AS item_status) B;

第四,我再放一个账号。

INSERT INTO account (account_id, account_pw) VALUES ('Judy', MD5('Judy')), ('Tom', MD5('Tom'));

第五,现在,我想给(=INSERT) 两个'magic_potion' 到新添加的帐户,并想添加(=UPDATE) 一个'magic_potion' 到以前的帐户。所以我做了以下查询。

INSERT
INTO    item
SELECT  NULL, A.account_id, item_name, item_count, item_status
FROM    account A
        CROSS JOIN (SELECT 'magic_potion' AS item_name, 3 AS item_count, 1 AS item_status) B
ON DUPLICATE KEY UPDATE item_name = 'magic_potion', item_count = item_count + 1, item_status = 1;

但是这个查询没有成功。系统消息说,

Error code: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'KEY UPDATE item_name = 'magic_potion', item_count = item_count + 1, item_status ' at line 6

我不知道我的查询有什么问题。

请帮帮我。

谢谢!

语法错误很容易——[CROSS] JOIN 可以带一个可选的 ON 子句,所以解析器认为 ON DUPLICATE ... 是这样一个子句。为避免语法错误,您需要将 SELECT 括在方括号中:

INSERT
INTO    item (
   SELECT  NULL, A.account_id, item_name, item_count, item_status
   FROM    account A
        CROSS JOIN (SELECT 'magic_potion' AS item_name, 3 AS item_count, 1 AS item_status) B
) ON DUPLICATE KEY UPDATE item_name = 'magic_potion', item_count = item_count + 1, item_status = 1;

请注意,CROSS 在这里是多余的。

然后你会遇到上下文问题(模棱两可item_count)。您还不需要解决它,因为查询无论如何都不会执行您期望的操作。它永远不会到达 ON DUPLICATE KEY UPDATE 子句,因为你唯一的唯一键是主键 item_no,而你正在向其中插入 NULL,这意味着它将始终通过自增生成-- 也就是说,您每次都会继续插入行。

对此有不同的解决方案,具体取决于您想要实现的目标——您可以修改查询,或者您可以在任何字段或组合中添加一个 UNIQUE KEY 应该是唯一的table(可能是 account_id,或者可能是 account_id + item_name 的组合——从数据样本中看不清楚)。