如何在SQL Server中将普通列转换为主键

时间:2019-02-05 12:07:52

标签: sql-server

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

在制作pk时出现此错误

SQL查询

Alter table Users
ADD Primary Key (UserID)

错误

  

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

3 个答案:

答案 0 :(得分: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

 | Duplicated ids |
 | -------------: |
 |              1 |
 |              4 |
 |              7 |
 

db <>提琴here

答案 1 :(得分:1)

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

您可以做两件事:

  • 删除重复的UserID。首先使用类似下面的查询找到重复的行。 RepeatRanking将显示每组相似的UserID的等级。您可以使用第二个查询来删除排名高于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
    
  • 将新的UserID分配给重复的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
    

答案 2 :(得分:0)

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

Alter table Users
ADD Primary Key (UserID)

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