我有一个名为UserID的列,表名称为Users。我想将UserID列作为主键。如何将现有列用作主键
在制作pk时出现此错误
SQL查询
Alter table Users
ADD Primary Key (UserID)
错误
CREATE UNIQUE INDEX语句由于重复的键而终止 找到对象名称“ dbo.Users”和索引名称 'pk_UserID'。重复的键值为(5)。
答案 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,但实际上他们是不同的用户。假设UserID
是INT
,则可以使用以下查询来重新分配重复的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
。