我在 SQL Server 上遇到问题。我有一个与此示例类似的表:
| RegisterId | Name | Phone | Email |
|------------|----------------|--------|--------------------------|
| XXX-00001 | John Strauss | 241567 | Null |
| XXX-00023 | Rick Astley | 241567 | [email protected] |
| XXX-00003 | John Strauss | NULL | NULL |
| XXX-00099 | NULL | 241567 | [email protected] |
| XXX-00085 | NULL | 256819 | [email protected] |
| XXX-00016 | NULL | NULL | [email protected] |
| XXX-00007 | John Deep | 280933 | NULL |
| XXX-00008 | John Deep | 93484 | NULL |
| XXX-00009 | Javier Estrada | 94578 | [email protected] |
您可以注意到我有重复的值。这是因为它们对应于同一个用户。发生这种情况的原因是这些值可能来自不同的数据库。 我想为他们分配一个新 ID,以将他们识别为同一个用户(理应如此),如果他们有:
类似这样的:
| RegisterId | Name | Phone | Email | UserId |
|------------|----------------|--------|--------------------------|--------|
| XXX-00001 | John Strauss | 241567 | Null | 1 |
| XXX-00023 | Rick Astley | 241567 | [email protected] | 1 |
| XXX-00003 | John Strauss | NULL | NULL | 1 |
| XXX-00099 | NULL | 241567 | [email protected] | 1 |
| XXX-00085 | NULL | 256819 | [email protected] | 1 |
| XXX-00016 | NULL | NULL | [email protected] | 1 |
| XXX-00007 | John Deep | 280933 | NULL | 2 |
| XXX-00008 | John Deep | 93484 | NULL | 2 |
| XXX-00009 | Javier Estrada | 94578 | [email protected] | 3 |
我尝试了 SQL 中的许多功能,甚至是一些 CTE,但我就是找不到实现它的方法。有人可以告诉我应该使用哪种近似值来解决这个问题吗?
总是可能存在冲突,并且根据您开始使用的用户,您可以获得不同的用户分组,但这是我的尝试:
--Pick one user
DECLARE @name varchar(200);
SET @name = (SELECT TOP(1) Name FROM Registers WHERE Name IS NOT NULL AND UserID IS NULL);
WHILE @name IS NOT NULL
BEGIN
PRINT '@name: '+@name;
--Get the next available UserID for this user
DECLARE @nextUserID int = (SELECT ISNULL(MAX(UserID), 0)+1 FROM Registers WHERE UserID IS NOT NULL);
PRINT ' @nextUserID: int = '+CAST(@nextUserID AS varchar);
-- Give the user their new userID
UPDATE Registers SET UserID = @nextUserID WHERE UserID IS NULL AND Name = @name;
--Keep looking for other rows that match this user in some way
DECLARE @rc int = 1;
WHILE @rc > 0
BEGIN
UPDATE Registers
SET UserID = @nextUserID
WHERE UserID IS NULL
AND (
Name IN (SELECT Name FROM Registers WHERE UserID = @nextUserID)
OR
Phone IN (SELECT Phone FROM Registers WHERE UserID = @nextUserID)
OR
Email IN (SELECT Email FROM Registers WHERE UserID = @nextUserID)
)
SET @rc = @@ROWCOUNT;
PRINT ' Rows updated: @rc='+CAST(@rc AS varchar);
--SELECT * FROM Registers
END
SET @name = (SELECT TOP(1) Name FROM Registers WHERE Name IS NOT NULL AND UserID IS NULL);
END
SELECT * FROM Registers
ORDER BY UserID;
给出结果:
| RegisterID | Name | Phone | Email | UserID |
|------------|----------------|--------|--------------------------|--------|
| XXX-00001 | John Strauss | 241567 | null | 1 |
| XXX-00003 | John Strauss | null | null | 1 |
| XXX-00016 | null | null | [email protected] | 1 |
| XXX-00023 | Rick Astley | 241567 | [email protected] | 1 |
| XXX-00085 | null | 256819 | [email protected] | 1 |
| XXX-00099 | null | 241567 | [email protected] | 1 |
| XXX-00007 | John Deep | 280933 | null | 2 |
| XXX-00008 | John Deep | 93484 | null | 2 |
| XXX-00009 | Javier Estrada | 94578 | [email protected] | 3 |
@name: John Strauss
@nextUserID: int = 1
Rows updated: @rc=2
Rows updated: @rc=2
Rows updated: @rc=0
@name: John Deep
@nextUserID: int = 2
Rows updated: @rc=0
@name: Javier Estrada
@nextUserID: int = 3
Rows updated: @rc=0