我在mysql数据库中有一个表QUES
。
该表格有一列BODY
,目前并不是唯一的。
该表有很多行,我相信当前BODY
本质上是唯一的,但未定义为属性。
如何使用唯一定义的属性更新列BODY
?
有人可以建议正确的sql查询吗?
感谢
答案 0 :(得分:0)
ALTER TABLE QUES ADD UNIQUE (BODY).
阅读精细手册here。
答案 1 :(得分:0)
以下是一些可帮助您入门的示例SQL语句。这假定body
是一个字符类型列,并且您想要“保留”尽可能多的现有值,并附加一个唯一的字符串以使其“更加独特”。
-- find values of `body` that are "duplicated" in the table
SELECT q.body
, COUNT(1) as cnt_
FROM ques q
GROUP BY q.body
HAVING COUNT(1) > 1
该查询只是获取body
的“重复”的特定值,以及共享该值的行数。我们需要能够识别具有这些唯一值的行,因此我们可以运行如下查询:
-- find all rows that have one of the "duplicated" values
SELECT s.id
, s.body
FROM (SELECT q.body
FROM ques q
WHERE q.body IS NOT NULL
GROUP BY q.body
HAVING COUNT(1) > 1
) r
JOIN ques s ON s.body = r.body
这些是我们需要更新的行。为了使这些唯一,我们可以为每个行的body
列分配一个新的唯一值。如果“新”值都没有重复表中已存在的值,我们将拥有唯一值。
示例更新声明:
-- append unique value to end of each body value
UPDATE (SELECT q.body
FROM ques q
WHERE q.body IS NOT NULL
GROUP BY q.body
HAVING COUNT(1) > 1
) r
JOIN ques s ON s.body = r.body
SET s.body = CONCAT(s.body,'<!--',s.id,'-->');
这里我们将一个值“追加”到现有体值的末尾。我们可以使用表中保证为NOT NULL且唯一的现有列。 AUTO_INCREMENT主键列是合适的候选者。 (我们可以让语句生成一个唯一的整数。)
注意:无法保证我们分配给body
的新值与数据库中已存在的值不同。我们只是识别现有的重复项,然后应用更改以使值彼此唯一。我们确实需要回圈,并再次检查重复值。
另请注意,此处没有检查body
列的最大长度,即每个现有值的末尾是否有“空格”来附加给定格式的字符串。因此,还有改进的余地,检查现有body
值的大小(使用LENGTH()
或CHAR_LENGTH()
函数)并将其与列定义进行比较。
此外,如果有2行具有重复值,我们实际上只需要更新其中一行,并且我们可以将其中一行保留为现有值。示例查询现在不执行此操作,但可以进行此操作。
但这应该足以让你开始。
当然,一旦你获得了唯一的值,你就会想要在这个列上添加一个UNIQUE约束,以防止将来创建重复。
这演示了我们如何将body的值保持不变。 (相应的UPDATE语句会将IF()
表达式赋值给body列。)
-- show new values for body, leave the value for one row unchanged
SELECT s.id
, s.body AS old_val
, IF(s.id = q.min_id, s.body, CONCAT(s.body,'<!--',s.id,'-->')) AS new_val
FROM (SELECT q.body
, MIN(q.id) AS min_id
FROM ques q
WHERE q.body IS NOT NULL
GROUP BY q.body
HAVING COUNT(1) > 1
) r
JOIN ques s ON s.body = r.body