【问题标题】:How to convert normal column as primary key in Sql server如何将普通列转换为Sql server中的主键
【发布时间】:2019-02-05 12:07:51
【问题描述】:

我有一个名为 UserID 的列,表名为 Users。我想将 UserID 列设为主键。如何将现有列作为主键

进行pk时遇到此错误

Sql查询

Alter table Users
ADD Primary Key (UserID)

错误

CREATE UNIQUE INDEX 语句因重复键而终止 找到对象名称“dbo.Users”和索引名称 'pk_UserID'。重复键值为 (5)。

【问题讨论】:

  • 检查列是否有重复条目
  • 你不能,如果列中的值不是唯一的并且为空
  • 这是因为您在字段 "UserID" 中有一个 "duplicate key"
  • 这是因为 userid 列中的重复值导致 userid 列中的值 5 重复
  • @SurajKumar 答案应该是评论。代码与 OP 相同,其余与其他 cmets 相同

标签: sql-server


【解决方案1】:

您在UserID 字段中有重复的值,这不能用作PRIMARY KEY,因为索引必须是唯一

如果要获取重复的 id,可以使用以下查询:

SELECT UserId AS "Duplicated ids"
FROM Users
GROUP BY UserId
HAVING COUNT(UserId) > 1;

例如:

 CREATE TABLE Users
 (
 UserId INT
 );

 INSERT INTO Users VALUES (1), (1), (2), (3), (4), (4), (4), (5), (6), (7), (7);

 SELECT UserId AS "Duplicated ids"
 FROM Users
 GROUP BY UserId
 HAVING COUNT(UserId) > 1;
 GO

|重复的 ID | | -------------: | | 1 | | 4 | | 7 |

db小提琴here

【讨论】:

    【解决方案2】:

    SQL Server 使用UNIQUE 索引在PRIMARY KEY 约束后面强制执行非重复值。这样做是出于性能原因。错误消息说,在尝试构建此索引时,UserID 列存在重复条目,因此无法创建索引,因此也无法创建主键。

    你可以做两件事:

    • 删除重复的用户 ID。首先使用如下查询找到重复的行。 RepeatRanking 将显示每组相似用户 ID 的排名。您可以使用第二个查询删除排名高于1的那些。您可以使用ORDER BY上的列列表来确定排名的第一个条目(您要保留的那个)。

      -- To query
      SELECT
          U.*,
          RepeatRanking = ROW_NUMBER() OVER (PARTITION BY U.UserID ORDER BY (SELECT NULL))
      FROM
          Users AS U
      ORDER BY
          RepeatRanking ASC
      
      
      -- To Delete:
      ;WITH UserRowNumbers AS
      (
          SELECT
              U.*,
              RepeatRanking = ROW_NUMBER() OVER (PARTITION BY U.UserID ORDER BY (SELECT NULL))
          FROM
              Users AS U
      )
      DELETE U FROM
          UserRowNumbers AS U
      WHERE
          U.RepeatRanking > 1
      
    • 将新的用户 ID 分配给重复的用户 ID(以防您不想删除它们)。为此,您要确定是否要保留所有当前用户,也许您重复了 UserID 但它们实际上是不同的用户。假设 UserIDINT,您可以使用以下查询重新分配重复的 UserID:

      DECLARE @MaxUserID INT = (SELECT MAX(UserID) FROM Users WITH(UPDLOCK))
      
      IF @MaxUserID IS NULL
          SET @MaxUserID = 0
      
      ;WITH UserRowNumbers AS
      (
          SELECT
              U.*,
              RepeatRanking = ROW_NUMBER() OVER (PARTITION BY U.UserID ORDER BY (SELECT NULL))
          FROM
              Users AS U
      )
      UPDATE U SET
          UserID = @MaxUserID + ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
      FROM
          UserRowNumbers AS U
      WHERE
          U.RepeatRanking > 1
      

    【讨论】:

      【解决方案3】:

      要将现有列设置为主键,请在查询窗口中运行以下 sql 脚本。

      Alter table Users
      ADD Primary Key (UserID)
      

      请注意,表中 UserID 的值不能重复。在这里您会收到错误,因为 UserId 中的值不止一次是 5

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-04
        • 1970-01-01
        • 2019-07-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多