合并 SQL 服务器中的记录
Merge records in SQL SERVER
我需要规范化 table 包含的数据。
这是一个包含一些行的示例 table:
Id LastName FirsName 地址 Email 电话 Mobile Age
1 罗西·马里奥 Via Milano NULL 123456 NULL 41
2 罗西马里奥 NULL rm@test.it 123456 NULL NULL
3 罗西·马里奥 Via Milano NULL NULL 254521 NULL
我想合并记录中的值,以便拥有一个包含所有值的唯一记录。
像这样:
Id LastName FirsName 地址 Email 电话 Mobile Age
1 罗西·马里奥 Via Milano rm@test.it 123456 254521 41
我尝试使用 MERGE 语句,但我认为这不是正确的解决方案。
感谢任何帮助。
我认为这可能对您有所帮助:-
UPDATE TAB_NAME
SET ID = MIN(ID), LastName = MAX(LastName), FirsName = MAX(FirsName)
Address = MAX(Address), Email = MAX(Email), Tel = MAX(Tel),
Mobile = MAX(Mobile), Age = MAX(Age)
WHERE COND.;
如果您考虑将 FirstName
和 LastName
作为关键标识符,那么您可以这样写:
SELECT MIN(Id),
T1.LastName ,
T1.FirsName,
SUBSTRING ((SELECT DISTINCT CASE WHEN T2.Address IS NULL
THEN '' ELSE ','+ T2.Address END
FROM @Test T2
WHERE T1.LastName = T2.LastName AND T1.FirsName = T2.FirsName
FOR XML PATH('')),2,8000) AS [Address],
SUBSTRING ((SELECT DISTINCT CASE WHEN T3.Email IS NULL
THEN '' ELSE ','+ T3.Email END
FROM @Test T3
WHERE T1.LastName = T3.LastName AND T1.FirsName = T3.FirsName
FOR XML PATH('')),2,8000)AS Email
FROM @Test T1
GROUP BY T1.LastName ,T1.FirsName
您正在查看两步操作。将合并的数据插入新的 table 然后删除原始 table 或使用合并的数据更新一行并删除所有额外的行。乍一看,前一种方法似乎最简单。
insert into NewTable( ID, LastName, FirstName, Address, Email, ...
select Min( ID ), LastName, FirstName, Min( Address ), Min( Email ), ...
from OldTable
group by LastName, FirstName;
drop OldTable;
exec sp_rename 'NewTable', 'OldTable'; -- Optional
但您可能没有删除和重命名 table 的权限。另外,您必须确保复制任何触发器、索引、约束等。
后一种方法在 DML 方面有点棘手,但更安全。
with
New as(
select Min( ID ) MinID, LastName, FirstName,
Min( Address ) MinAddr, Min( Email ) MinEmail,
Min( Tel ) MinTel, Min( Mobile ) MinMobil, Min( Age ) MinAge
from OldTable
group by LastName, FirstName
)
update Old
set Old.Address = New.MinAddr,
Old.Email = New.MinEmail,
Old.Tel = New.MinTel,
Old.Mobile = New.MinMobil,
Old.Age = New.MinAge
from OldTable Old
join New
on New.MinID = Old.ID;
select * from OldTable;
with
MinIDs as(
select Min( ID ) MinID, LastName, FirstName
from OldTable
group by LastName, FirstName
)
delete from Old
from OldTable Old
join MinIDs MI
on MI.MinID < Old.ID;
如果您对非关键字段使用 Min
或 Max
真的没有关系。这是后一种方法的Fiddle。
我需要规范化 table 包含的数据。 这是一个包含一些行的示例 table:
Id LastName FirsName 地址 Email 电话 Mobile Age 1 罗西·马里奥 Via Milano NULL 123456 NULL 41 2 罗西马里奥 NULL rm@test.it 123456 NULL NULL 3 罗西·马里奥 Via Milano NULL NULL 254521 NULL
我想合并记录中的值,以便拥有一个包含所有值的唯一记录。 像这样:
Id LastName FirsName 地址 Email 电话 Mobile Age 1 罗西·马里奥 Via Milano rm@test.it 123456 254521 41
我尝试使用 MERGE 语句,但我认为这不是正确的解决方案。
感谢任何帮助。
我认为这可能对您有所帮助:-
UPDATE TAB_NAME
SET ID = MIN(ID), LastName = MAX(LastName), FirsName = MAX(FirsName)
Address = MAX(Address), Email = MAX(Email), Tel = MAX(Tel),
Mobile = MAX(Mobile), Age = MAX(Age)
WHERE COND.;
如果您考虑将 FirstName
和 LastName
作为关键标识符,那么您可以这样写:
SELECT MIN(Id),
T1.LastName ,
T1.FirsName,
SUBSTRING ((SELECT DISTINCT CASE WHEN T2.Address IS NULL
THEN '' ELSE ','+ T2.Address END
FROM @Test T2
WHERE T1.LastName = T2.LastName AND T1.FirsName = T2.FirsName
FOR XML PATH('')),2,8000) AS [Address],
SUBSTRING ((SELECT DISTINCT CASE WHEN T3.Email IS NULL
THEN '' ELSE ','+ T3.Email END
FROM @Test T3
WHERE T1.LastName = T3.LastName AND T1.FirsName = T3.FirsName
FOR XML PATH('')),2,8000)AS Email
FROM @Test T1
GROUP BY T1.LastName ,T1.FirsName
您正在查看两步操作。将合并的数据插入新的 table 然后删除原始 table 或使用合并的数据更新一行并删除所有额外的行。乍一看,前一种方法似乎最简单。
insert into NewTable( ID, LastName, FirstName, Address, Email, ...
select Min( ID ), LastName, FirstName, Min( Address ), Min( Email ), ...
from OldTable
group by LastName, FirstName;
drop OldTable;
exec sp_rename 'NewTable', 'OldTable'; -- Optional
但您可能没有删除和重命名 table 的权限。另外,您必须确保复制任何触发器、索引、约束等。
后一种方法在 DML 方面有点棘手,但更安全。
with
New as(
select Min( ID ) MinID, LastName, FirstName,
Min( Address ) MinAddr, Min( Email ) MinEmail,
Min( Tel ) MinTel, Min( Mobile ) MinMobil, Min( Age ) MinAge
from OldTable
group by LastName, FirstName
)
update Old
set Old.Address = New.MinAddr,
Old.Email = New.MinEmail,
Old.Tel = New.MinTel,
Old.Mobile = New.MinMobil,
Old.Age = New.MinAge
from OldTable Old
join New
on New.MinID = Old.ID;
select * from OldTable;
with
MinIDs as(
select Min( ID ) MinID, LastName, FirstName
from OldTable
group by LastName, FirstName
)
delete from Old
from OldTable Old
join MinIDs MI
on MI.MinID < Old.ID;
如果您对非关键字段使用 Min
或 Max
真的没有关系。这是后一种方法的Fiddle。