2017-05-29 106 views
0

我有一个带有displayName列的表,我添加了一个“唯一”约束。我试图编写一个迁移,将任何非唯一的displayName设置为null,只保留具有较低用户ID的displayName。这里是我的查询:在添加唯一约束的列中删除重复的值

UPDATE "User" SET "displayName" = NULL 
      WHERE id IN (SELECT id, 
         FROM (SELECT id, 
            ROW_NUMBER() OVER (partition BY "displayName" ORDER BY id) AS rnum 
           FROM "User") t 
         WHERE t.rnum > 1); 

当我试图运行迁移我回来了“错误:语法错误在或接近”FROM“”。

感谢

+0

用您正在使用的数据库标记您的问题。此外,样本数据和期望的结果将有助于传达您正在使用的内容。 –

+3

','在子查询中的id后面。 –

回答

1

为什么不直接写为:

UPDATE "User" 
    SET "displayName" = NULL 
    WHERE id > (SELECT MIN(u2.id) 
       FROM "User" u2 
       WHERE u2."displayName" = u."displayName" 
       ); 

无论数据库使用的是,这也应该是能够在"User"("displayName", id)采取指数的优势。

0

更简单的方法是使用CTE或子查询,像这样....

WITH X AS 
(
SELECT id 
    , [displayName] 
    , ROW_NUMBER() OVER (partition BY [displayName] ORDER BY id) AS rnum 
FROM [User] 
) 
UPDATE X 
SET [displayName] = NULL 
WHERE rnum > 1 

OR

UPDATE X 
SET [displayName] = NULL 
FROM (
     SELECT id 
      , [displayName] 
      , ROW_NUMBER() OVER (partition BY [displayName] ORDER BY id) AS rnum 
     FROM [User] 
    ) x 
WHERE rnum > 1 

而且在一个侧面说明,在唯一约束显示名称真的:S ....

+0

老板的命令。绝对不是我的想法。 – user3143105

+0

请注意,方括号在SQL标识符中无效。而问题只是用'sql'标记而不是特定的DBMS产品(并且该问题也使用标准双引号) –