NodeJS + MySQL,UPDATE带有JOIN,模糊的列名

时间:2017-08-24 05:08:10

标签: mysql node.js sql-update

首先,我理解为什么我会收到此错误消息,而且我知道解决问题的方法,但我希望能提供比我想象的更有效的方法。这基本上就是我所拥有的:

UPDATE customer c 
    JOIN customer d ON c.customer_id = d.parent_customer_id
    SET ? 
    WHERE d.customer_type = "Big Cheese";

因此,数据被输入到"?"参数如下所示:

{"customer_id": 10, "customer_name": "Cheese-It", ... }

问题是,因为我加入的是基本上自己的表,所有列都具有相同的名称。我知道如何解决这个问题的唯一方法是编辑JSON并使用所需的别名为所有字段添加前缀:

{"c.customer_id": 10, "c.customer_name": "Cheese-It", ... }

我希望有一种更优雅的方式来解决这个问题。有没有办法重构我的SQL,以便它知道我想要更新哪个表别名?有什么想法吗?

2 个答案:

答案 0 :(得分:0)

子查询将执行您想要的操作,但实际上效率较低,因为WHERE子句中的子查询通常是性能杀手。我觉得你必须将JSON解析为SQL,所以我只想在那时添加别名。

无论如何,作为参考,以下是如何重构SQL以不需要别名:

UPDATE customer
SET ?
WHERE customer_id IN (
    SELECT c.customer_id
    FROM customer c
    JOIN customer d ON c.customer_id = d.parent_customer_id
    WHERE d.customer_type = 'Big Cheese'
);

注意:这是未经测试的

修改

第二个想法,EXISTS条款对于性能会略好一些:

UPDATE customer c
SET ?
WHERE EXISTS (
    SELECT 1
    FROM customer d
    WHERE d.parent_customer_id = c.customer_id
        AND d.customer_type = 'Big Cheese'
);

无论哪种方式都应该有效。只要您在更新中没有JOINSET列只能引用一个表,这样您就可以避免出现模糊的列名错误。

答案 1 :(得分:0)

我知道这是一个比较老的问题,但是我发现了一个更好的解决方案,并且没有影响性能。您可以在要更新的对象中的属性名称中添加别名。

这是帮助功能,用于使用别名转换标准属性名称。

const allowUpdate = ['name']

function addUpdateAlias(updated, alias) {
  let validUpdate = {}
  for (let p in updated) {
    if (allowUpdate.indexOf(p) > -1) {
      validUpdate[`${alias}.${p}`] = updated[p]
    }
  }

  return validUpdate;
}

现在,使用上面的函数包装要更新的对象,并在更新中应用别名!

您的参数将为:[addUpdateAlias(customer, 'c')],以传递到原始查询中。