-1

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

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

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

如何更新BODY具有唯一定义为属性的列?

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

谢谢

4

2 回答 2

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,'-->');

在这里,我们将一个值“附加”到现有主体值的末尾。我们可以利用表中保证不为空且唯一的现有列。AUTO_INCREMENT 主键列是合适的候选者。(我们可以让语句生成一个唯一的整数。)

注意:不能保证我们分配的新值body与数据库中已经存在的值不同。我们只是识别现有的重复项,然后应用更改以使这些值彼此唯一。我们真的需要回过头来,再次检查重复值。

另请注意,这里没有检查body列的最大长度,即每个现有值的末尾是否有“空间”来附加给定格式的字符串。所以那里还有改进的空间,检查现有body值的大小(使用LENGTH()orCHAR_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
于 2012-07-19T14:52:10.163 回答
0
ALTER TABLE QUES ADD UNIQUE (BODY).

在这里阅读精美的手册。

于 2012-07-19T13:54:54.317 回答