3

我需要根据另一列中的 id 更新特定列中的单元格。列名是Prod_ID和:Lang_IDDescr

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行匹配。

4

3 回答 3

2

您在其他地方的评论中提到“master” lang_id 始终为 1。这大大简化了事情,您可以通过简单的自联接来做到这一点(没有子查询 :-)

此查询选择所有 lang_1 行,然后将它们与具有相同 prod_id 的所有非 lang_1 行连接并更新它们。

如果 Lang_ID=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=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

请注意,虽然它确实使用了子查询,但它并没有嵌套它们。子查询实质上只是向 products 表(实际上)添加了一个具有最低 Lang_ID 值的列,然后允许自连接匹配该列。因此,如果存在具有 Lang_ID 3、4 和 5 的产品,这会将所有产品上的 Descr 设置为为 Lang_ID 3 设置的任何内容。

于 2012-07-11T07:45:19.910 回答
1

这个怎么样?

UPDATE myTable dt1, myTable dt2 
SET dt1.Descr = dt2.Descr
WHERE dt1.Prod_ID=dt2.Prod_ID;

在 sqlfiddle 演示

于 2012-07-11T08:09:04.253 回答
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),它也可以工作,但在这种情况下,可能会出现像这样的不太复杂的查询。

于 2012-07-10T16:11:13.857 回答