使用HAVING子句更新MySQL表

使用HAVING子句更新MySQL表,mysql,unique-key,Mysql,Unique Key,我为一个表创建了slug字段,它们需要是唯一的,但其中一些不是唯一的,所以我想我可以在它们的末尾添加随机字符以使它们唯一 这是我的选择查询: SELECT slug,count(*) as num FROM table GROUP BY slug HAVING num > 1 这是更新查询: UPDATE table SET slug = CONCAT(slug,'-',SUBSTRING(MD5(NOW()),1,2)) 我无法将这两个查询组合起来。您可以使用加入: UPDATE m

我为一个表创建了slug字段,它们需要是唯一的,但其中一些不是唯一的,所以我想我可以在它们的末尾添加随机字符以使它们唯一

这是我的选择查询:

SELECT slug,count(*) as num FROM table GROUP BY slug HAVING num > 1
这是更新查询:

UPDATE table SET slug = CONCAT(slug,'-',SUBSTRING(MD5(NOW()),1,2))

我无法将这两个查询组合起来。

您可以使用
加入

UPDATE mytable AS m
JOIN (SELECT slug
      FROM mytable 
      GROUP BY slug 
      HAVING COUNT(*) > 1) t
ON m.slug = t.slug      
SET m.slug = CONCAT(m.slug,'-',SUBSTRING(MD5(NOW()),1,2))
但是,上面的问题是,它不会生成唯一的字符串值

解决此问题的一种方法是使用由变量计算的行号:

UPDATE mytable AS m
CROSS JOIN (SELECT @row_number:=0, @slug := '') AS vars 
JOIN (
   SELECT slug
   FROM mytable 
   GROUP BY slug 
   HAVING COUNT(*) > 1 ) AS t ON m.slug = t.slug       
SET m.slug = CONCAT(m.slug, 
                    '-',
                    IF (@slug = m.slug,
                         IF (@slug := m.slug,@row_number:=@row_number+1, 
                                             @row_number:=@row_number+1),
                         IF (@slug := m.slug, @row_number:=1, 
                                              @row_number:=1)) 
                   )
试试:

UPDATE t ,
(  SELECT slug FROM t 
  GROUP BY slug HAVING count(*) > 1
) x
SET  t.slug = CONCAT(t.slug,'-',SUBSTRING(MD5(rand()),1,2))
WHERE t.slug = x.slug
;
演示:


我使用的是
rand()
而不是
now()
,因为后者不会给出唯一的字符串。

要使用
HAVING
,还必须使用
groupbyslug
。否则,MySQL可能会给您错误的结果(大多数其他RDBMS会报告解析错误)您的目标是修改第一次查询返回的行吗?因为我忘了写group by,我编辑了查询,谢谢。是的,我的目标是修改第一个查询返回的行。但是如果给定非唯一值,您是要保留其中一个查询的原始行,还是要添加到所有查询?请发布输入和输出的示例表。是的,其中一个可以保留,但其他的应该随机修改,以便它们是唯一的。你可以在这里看到一些鼻涕虫和它们的数量:你的第二个建议解决了我的问题,谢谢。