如何使MySQL表中的列唯一?

时间:2012-07-19 13:46:51

标签: mysql sql

我在mysql数据库中有一个表QUES

该表格有一列BODY,目前并不是唯一的。

该表有很多行,我相信当前BODY本质上是唯一的,但未定义为属性。

如何使用唯一定义的属性更新列BODY

有人可以建议正确的sql查询吗?

感谢

2 个答案:

答案 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