【问题标题】:Error 1064 when using SQL with INSERT INTO ... SELECT ... ON DUPLICATE KEY UPDATE使用带有 INSERT INTO ... SELECT ... ON DUPLICATE KEY UPDATE 的 SQL 时出现错误 1064
【发布时间】:2019-04-29 05:20:49
【问题描述】:

我正在尝试使用“INSERT INTO ... SELECT ON DUPLICATE KEY UPDATE 功能”,但我现在遇到了麻烦。

我想向“fruitProperty”表中插入数据。

我的查询如下:

START TRANSACTION;

SET @myVal1 := "";
SET @myVal2 := 0;
SET @myVal3 := 0;
SET @myVal4 := 0;
SET @myVal5 := 0;

SELECT masterIndex INTO @myVal1 FROM fruitMaster WHERE masterName = 'apple';
SELECT masterIndex INTO @myVal2 FROM fruitMaster WHERE masterName = 'banana';
SELECT masterIndex INTO @myVal3 FROM fruitMaster WHERE masterName = 'mango';
SELECT masterIndex INTO @myVal4 FROM fruitMaster WHERE masterName = 'melon';
SELECT masterIndex INTO @myVal5 FROM fruitMaster WHERE masterName = 'grape';

INSERT
INTO    fruitProperty
        (fruitID, masterIndex, cpValue)
SELECT  A1.fruitID, A2.masterIndex, A2.cpValue
FROM    (   
           SELECT   A.fruitID
           FROM     fruit A
                    JOIN fruitProperty B ON A.fruitID = B.fruitID
           WHERE    B.masterIndex = @myVal1 AND B.cpValue = 1
        ) A1
        CROSS JOIN
        (
           SELECT @myVal2 AS masterIndex, 1 AS cpValue
           UNION
           SELECT @myVal3, 1
           UNION
           SELECT @myVal4, 1
           UNION
           SELECT @myVal5, 1
       ) A2
ON DUPLICATE KEY UPDATE cpValue = cpValue + 1;

ROLLBACK;

我遇到了错误代码。

错误代码:1064 您的 SQL 语法有错误;检查 与您的 MariaDB 服务器版本相对应的手册 在第 21 行的“KEY UPDATE cpValue = 1”附近使用的语法

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

谢谢。

【问题讨论】:

    标签: mysql sql mariadb


    【解决方案1】:

    如果你使用显式的join,你会遇到问题吗:

    INSERT INTO fruitProperty (fruitID, masterIndex, cpValue)
    SELECT f.fruitID, A2.masterIndex, A2.cpValue
    FROM (SELECT f.fruitID
          FROM fruit f JOIN
               fruitProperty fp
                ON f.fruitID = fp.fruitID
          WHERE f.masterIndex = @myVal1 AND fp.cpValue = 1
         ) f JOIN
         (SELECT @myVal2 AS masterIndex, 1 AS cpValue
          UNION ALL
          SELECT @myVal3, 1
          UNION ALL
          SELECT @myVal4, 1
          UNION ALL
          SELECT @myVal5, 1
         ) A2
         ON 1=1
    ON DUPLICATE KEY UPDATE cpValue = VALUES(cpValue) + 1;
    

    我怀疑问题是解析问题,因为 MySQL/MariaDB 支持 CROSS JOIN 的 ON 子句(糟糕!!!)。但是ON 关键字会混淆。

    【讨论】:

    • 我已按照您的建议更改了查询,但出现了另一个错误。它说“错误代码:字段列表中的 1052 列 'cpValue' 不明确”。而'ON 1=1'是什么意思???
    • @passion053 。 . .可能你想增加值,所以使用VALUES()。
    【解决方案2】:

    也许您可以在不使用 CROSS JOIN 的情况下简化它。

    在 MySql 中,CROSS JOIN 只是 INNER JOIN 的同义词。

    但您不希望最后一个 ON 关键字作为 JOIN 的一部分而混淆。

    样本数据

    create table fruitMaster (masterIndex int primary key, masterName varchar(30));
    
    insert into fruitMaster (masterIndex, masterName) values 
    (1, 'apple'),(2, 'banana'),(3, 'mango'),(4, 'melon'),(5, 'grape'), (6, 'prune');
    
    create table fruit (fruitID int primary key, fruitName varchar(30));
    
    insert into fruit (fruitID, fruitName) values 
    (10,'jonagold'),(20,'straight banana'),(40,'big melons');
    
    create table fruitProperty (
     fruitID int, masterIndex int, cpValue int,
     primary key (fruitID, masterIndex));
    
    insert into fruitProperty (fruitID, masterIndex, cpValue) values
    (10, 1, 1),(10, 2, 1),(10, 6, 1),
    (20, 2, 1),(30, 3, 1),(40, 4, 1);
    

    插入查询

    INSERT INTO fruitProperty (fruitID, masterIndex, cpValue)
    SELECT F.fruitID, FM2.masterIndex, 1 AS cpValue
    FROM fruit F
    JOIN fruitProperty FP ON (FP.fruitID = F.fruitID AND FP.cpValue = 1)
    JOIN fruitMaster FM1 ON (FM1.masterIndex = FP.masterIndex AND FM1.masterName = 'apple')
    JOIN fruitMaster FM2 ON FM2.masterName IN ('banana', 'mango', 'melon', 'grape')
    ON DUPLICATE KEY UPDATE cpValue = 2;
    

    结果:

    SELECT * FROM fruitProperty;
    
    水果ID |主索引 | cp值 ------: | ----------: | ------: 10 | 1 | 1 10 | 2 | 2 10 | 3 | 1 10 | 4 | 1 10 | 5 | 1 10 | 6 | 1 20 | 2 | 1 30 | 3 | 1 40 | 4 | 1

    db小提琴here

    【讨论】:

    • “在 MySql 中,CROSS JOIN 只是 INNER JOIN 的同义词。但您不希望最后一个 ON 关键字作为 JOIN 的一部分而混淆。”你给了我们灵感。我真的很感谢你。非常感谢。
    猜你喜欢
    • 2011-01-29
    • 2022-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-21
    • 1970-01-01
    • 2016-10-29
    • 1970-01-01
    相关资源
    最近更新 更多