[英]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
子句有信心,可以跳过它。
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
子句。
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. 就这样。
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. 将
EXPLAIN
到SELECT
查询中,以检查执行计划并确定您需要哪些索引。
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 BY
和LIMIT
以使用无法使用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_id
和category_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.