使用同一个表中的列更新行

时间:2017-08-23 14:13:35

标签: mysql sql database

我的桌子看起来像这样:

id_product  | id_code | content
----------- | ------- | -------------------
1           | 1       | a
1           | 2       | ''
1           | 3       | ''
2           | 1       | b
2           | 2       | ''
2           | 3       | ''
3           | 1       | c
3           | 2       | ''
3           | 3       | ''

我想要达到的结果是这样的:

id_product  | id_code | content
----------- | ------- | -------------------
1           | 1       | a
1           | 2       | a
1           | 3       | a
2           | 1       | b
2           | 2       | b
2           | 3       | b
3           | 1       | c
3           | 2       | c
3           | 3       | c

简而言之,我希望查询能够为每个id_product复制内容列,其中id_code为1。

AFAIK它需要一个结合连接的更新查询,但我不确定如何将它串在一起。最难的部分似乎是使其动态化,以便它可以对所有id_products执行查询。

如果需要更多信息,请告诉我。

以下是演示的链接:https://www.db-fiddle.com/f/2bmVgH9h2Q9uUrp7Q1MfR6/0

3 个答案:

答案 0 :(得分:4)

感谢每个id_product组记录都有一个content值,该值不是空字符串(或NULL?)。我们可以使用子查询为每个content组提取此非空id_product值,然后使用连接更新查询来填充空格。

UPDATE product p1
INNER JOIN
(
    SELECT id_product, MAX(content) AS content
    FROM products
    GROUP BY id_product
) p2
    ON p1.id_product = p2.id_product
SET p1.content = p2.content

在此处使用MAX技巧可行,因为任何字母都大于空字符串,并且MAX也会忽略NULL值,因此我们在任何一种情况下均会受到保护。

请注意,我没有WHERE子句,因为每个id_product组的所有content值都相同。

答案 1 :(得分:2)

鉴于您的数据结构,这应该有效:

update t join
       t t2
       on t2.id_product = t.id_product and t2.id_code = 1
    set t.content = t2.content
    where t.id_code > 1;
蒂姆的答案是更一般的答案。如果您的索引位于t(id_product, id_code)或更好t(id_product, id_code, content),则此答案的效果应该更好。或者,如果您的意图始终是使用id_code = 1的值。

答案 2 :(得分:1)

您可以使用别名执行SELF JOIN,请尝试以下查询:

UPDATE products p 
JOIN 
(SELECT a.content, a.id_product FROM 
    (SELECT content, id_product, id_code FROM products) a) b
ON p.id_product = b.id_product AND b.content <> ''
SET p.content = b.content;