MySQL错误1242 - 子查询返回超过1行

时间:2015-01-15 12:12:07

标签: php mysql database

我在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
)

2 个答案:

答案 0 :(得分:1)

解决方案非常简单,可以通过两个简单的步骤完成。第一步是预览将要更改的内容,以避免破坏数据。如果您对WHERE条款有信心,可以跳过它。

第1步:预览更改

使用您想要匹配的字段加入表格,选择所有内容以进行匹配的视觉验证。

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子句。

第2步:进行实际更新

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 BYLIMIT,以使用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_idtable2对的列表。然后你可以决定做什么。您想要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
                      );