我在DB中有两个表,结构如下:
表1:3行 - category_id,product_id和position
表2:3行 - category_id,product_id和position
我正在尝试将表1的位置设置为表2的位置,其中类别和产品ID与表格相同。
下面是我试图让这种情况发生的sql但返回MySQL错误1242 - 子查询返回多于1行
UPDATE table1
SET position = (
SELECT position
FROM table2
WHERE table1.product_id = table2.product_id AND table1.category_id = table2.category_id
)
答案 0 :(得分:1)
解决方案非常简单,可以通过两个简单的步骤完成。第一步是预览将要更改的内容,以避免破坏数据。如果您对WHERE
条款有信心,可以跳过它。
使用您想要匹配的字段加入表格,选择所有内容以进行匹配的视觉验证。
SELECT t1.*, t2.*
FROM table1 t1
INNER JOIN table2 t2
ON t1.category_id = t2.category_id
AND t1.product_id = t2.product_id
如果只需要修改某些行,也可以添加WHERE
子句。
将SELECT
子句和FROM
关键字替换为UPDATE
,添加它所属的SET
子句。保留WHERE
子句:
UPDATE table1 t1
INNER JOIN table2 t2
ON t1.category_id = t2.category_id
AND t1.product_id = t2.product_id
SET t1.position = t2.position
就是这样。
当表有超过几百行时,必须在两个表的JOIN
子句上使用的列的索引。如果查询没有WHERE
条件,那么MySQL将仅为最大的表使用索引。 WHERE
条件上使用的字段的索引将加快查询速度。将EXPLAIN
添加到SELECT
查询中以检查执行计划并确定您需要哪些索引。
您可以添加SORT BY
和LIMIT
,以使用WHERE
无法实现的条件进一步减少已更改的行集(例如,仅最新/最旧的100行等) )。首先将它们放在SELECT
查询上以验证结果,然后将SELECT
变形为UPDATE
,如上所述。
当然,SORT BY
子句上使用的列的索引是必须的。
答案 1 :(得分:0)
您可以运行此查询以查看发生的情况:
SELECT product_id, category_id, count(*), min(position), max(position)
FROM table2
GROUP BY product_id, category_id
HAVING COUNT(*) > 1;
这将为您提供在product_id
中多次出现的category_id
,table2
对的列表。然后你可以决定做什么。您想要position
的任意值吗? position
的值是否始终相同?你需要修理桌子吗?
使用limit 1
或聚合函数修复特定问题非常容易。但是,您可能真的需要修复表中的数据。修复如下:
UPDATE table1 t1
SET t1.position = (SELECT t2.position
FROM table2 t2
WHERE t2.product_id = t1.product_id AND t2.category_id = t1.category_id
LIMIT 1
);