我需要根据另一列中的ID更新特定列中的单元格。列名称为Prod_ID
,Lang_ID
和Descr
:
Prod_ID | Lang_ID | Descr
--------+---------+------
A101 | 1 | TextA
A101 | 2 | TextB
A101 | 3 | TextC
对于具有相同Prod_ID
的一组行,我需要将所有后续描述(Descr
列)替换为第一行的描述。具有正确描述的行始终为Lang_ID = 1
。此外,该表可能不按Lang_ID排序。
示例:TextA
(Lang_ID = 1)应替换TextB
和TextC
,因为行的Prod_IDs
匹配。
答案 0 :(得分:2)
你在其他地方的评论中提到“主”lang_id总是1.这大大简化了事情,你可以通过一个简单的自连接(没有子查询: - )
来实现这一点。此查询选择所有lang_1行,然后将它们与同一prod_id的所有非lang_1行连接并更新它们。
UPDATE products
LEFT JOIN products as duplicates
ON products.Prod_ID=duplicates.Prod_ID
AND duplicates.Lang_ID != 1
SET duplicates.Descr = products.Descr
WHERE products.Lang_ID = 1
您可以通过中间连接将表连接到自身,该连接找到该行的最低Lang_ID。我已经调用了中间连接“lang_finder”。
UPDATE products
LEFT JOIN (SELECT Prod_ID, MIN(Lang_ID) as Lang_ID FROM products GROUP BY Prod_ID) as lang_finder
ON products.prod_id=lang_finder.prod_id
LEFT JOIN products as cannonical_lang
ON products.Prod_ID = cannonical_lang.Prod_ID
AND lang_finder.Lang_ID = cannonical_lang.Lang_ID
SET products.Descr = cannonical_lang.Descr
请注意,虽然它确实使用子查询,但它不会嵌套它们。子查询基本上只是将一个列(虚拟地)添加到具有最低Lang_ID值的产品表中,然后允许自联接匹配该列。所以 if 有一个产品有Lang_ID 3,4,& 5,这会将所有这些上的描述设置为为Lang_ID 3设置的任何内容。
答案 1 :(得分:1)
这个怎么样?
UPDATE myTable dt1, myTable dt2
SET dt1.Descr = dt2.Descr
WHERE dt1.Prod_ID=dt2.Prod_ID;
答案 2 :(得分:0)
假设正确的描述始终位于具有相同Prod_ID的行的行中,其中Lang_ID具有最小值,则此MySQL查询应该有效:
UPDATE your_table AS t1
JOIN (
SELECT Prod_ID, Descr
FROM (
SELECT *
FROM your_table
ORDER BY Lang_ID
) AS t3
GROUP BY Prod_ID
) AS t2
ON t1.Prod_ID = t2.Prod_ID
SET t1.Descr = t2.Descr;
以上可以使用例如如果Lang_ID是主键或唯一键。如果相应的Lang_ID始终具有相同的最小值(例如= 1),它也可以工作,但在这种情况下,可能会有更复杂的查询like this one。