简体   繁体   English

MySQL错误1242-子查询返回多于1行

[英]MySQL error 1242 - Subquery returns more than 1 row

i have two tables in a DB with the following structure: 我在数据库中具有以下结构的两个表:

table 1: 3 rows - category_id, product_id and position 表1:3行-category_id,product_id和排名

table 2: 3 rows - category_id, product_id and position 表2:3行-category_id,product_id和排名

i am trying to set table 1 position to table 2 position where category and product id is the same from the tables. 我试图将表1的位置设置为表2的位置,其中类别和产品ID与表中的相同。

below is the sql i have tried to make this happen but returns MySQL error 1242 - subquery returns more then 1 row 下面是我试图做到这一点的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
)

The solution is very simple and it can be done in two simple steps. 该解决方案非常简单,可以通过两个简单步骤完成。 The first step is just a preview of what will be changed, to avoid destroying data. 第一步只是预览要更改的内容,以避免破坏数据。 It can be skipped if you are confident of your WHERE clause. 如果您对WHERE子句有信心,可以跳过它。

Step 1: preview the changes 步骤1:预览变更

Join the tables using the fields you want to match, select everything for visual validation of the match. 使用您要匹配的字段将表连接起来,选择所有内容以进行视觉验证。

SELECT t1.*, t2.*
FROM table1 t1
    INNER JOIN table2 t2
        ON t1.category_id = t2.category_id
        AND t1.product_id = t2.product_id

You can also add a WHERE clause if only some of the rows must be modified. 如果仅必须修改某些行,则还可以添加WHERE子句。

Step2: do the actual update 步骤2:进行实际更新

Replace the SELECT clause and the FROM keyword with UPDATE , add the SET clause where it belongs. UPDATE替换SELECT子句和FROM关键字,然后在它所属的SET子句中添加。 Keep the WHERE clause: 保留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

That's all. 就这样。

Technical considerations 技术注意事项

Indexes on the columns used on the JOIN clause on both tables are a must when the tables have more than several hundred rows. 当表的行数超过数百时,必须在两个表的JOIN子句中使用的列索引。 If the query doesn't have WHERE conditions then MySQL will use indexes only for the biggest table. 如果查询没有WHERE条件,则MySQL将仅对最大的表使用索引。 Indexes on the fields used on the WHERE condition will speed up the query. WHERE条件下使用的字段上的索引将加快查询速度。 Prepend EXPLAIN to the SELECT query to check the execution plan and decide what indexes do you need. EXPLAINSELECT查询中,以检查执行计划并确定您需要哪些索引。

You can add SORT BY and LIMIT to further reduce the set of changed rows using criteria that cannot be achieved using WHERE (for example, only the most recent/oldest 100 rows etc). 您可以添加SORT BYLIMIT以使用无法使用WHERE达到的条件(例如,仅最新/最旧的100行等)进一步减少已更改行的集合。 Put them on the SELECT query first to validate the outcome then morph the SELECT into an UPDATE as described. 首先将它们放在SELECT查询上,以验证结果,然后按照说明将SELECT转换为UPDATE Of course, indexes on the columns used on the SORT BY clause are a must. 当然,必须在SORT BY子句上使用的列上的索引。

You can run this query to see what is happening: 您可以运行此查询以查看发生了什么:

SELECT product_id, category_id, count(*), min(position), max(position)
FROM table2
GROUP BY product_id, category_id
HAVING COUNT(*) > 1;

This will give you the list of product_id , category_id pairs that appear multiple times in table2 . 这将为您提供在table2多次出现的product_idcategory_id对的列表。 Then you can decide what to do. 然后,您可以决定要做什么。 Do you want an arbitrary value of position ? 您想要一个任意的position值吗? Is the value of position always the same? position值是否始终相同? Do you need to fix the table? 您需要修桌子吗?

It is easy enough to fix the particular problem by using limit 1 or an aggregation function. 通过使用limit 1或聚合函数来解决特定问题很容易。 However, you may really need to fix the data in the table. 但是,您可能确实需要修复表中的数据。 A fix looks like: 修复程序如下所示:

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
                      );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM