我有一个如下所示的表,我想使用函数或过程或块通过传递两个值来合并它,如下所示。 101,102
如果两个不同 ID 的 ident 和 val 相同,则在合并期间忽略该记录,在终止它们的情况下,可以获取 sysdate 或 getdate 来关闭。
102 中的所有记录都将被排除,除非 Ident 和 val 相同,在这种情况下我们忽略该记录。还可以在代码中找到创建表脚本。
身份证 | 身份 | 来源 | 瓦尔 | 开放日期 | 已关闭 | 处于活动状态 |
---|---|---|---|---|---|---|
101 | euid01 | 文件01 | x010 | 2023年1月1日 | 01-01-2999 | 1 |
101 | euid02 | 文件01 | x111 | 2023年1月1日 | 01-01-2999 | 1 |
101 | euid02 | 文件01 | x222 | 2023年1月1日 | 2024年10月1日 | 0 |
102 | euid01 | 文件11 | x010 | 2023年1月1日 | 01-01-2999 | 1 |
102 | euid02 | 文件12 | x333 | 2023年1月1日 | 01-01-2999 | 1 |
102 | euid02 | 文件10 | x444 | 2023年1月1日 | 2024年10月1日 | 0 |
输出如下
身份证 | 身份 | 来源 | 瓦尔 | 开放日期 | 已关闭 | 处于活动状态 |
---|---|---|---|---|---|---|
101 | euid01 | 文件01 | x010 | 2023年1月1日 | 01-01-2999 | 1 |
101 | euid02 | 文件01 | x111 | 2023年1月1日 | 01-01-2999 | 1 |
101 | euid02 | 文件01 | x222 | 2023年1月1日 | 2024年10月1日 | 0 |
101 | euid02 | 文件12 | x333 | 2023年1月1日 | 2024年10月22日 | 0 |
101 | euid02 | 文件10 | x444 | 2023年1月1日 | 2024年10月22日 | 0 |
CREATE TABLE MDM (
ID INT,
Ident VARCHAR(20),
source VARCHAR(20),
val VARCHAR(20),
opendate datetime,
closedate datetime,
Isactive bit)
insert into MDM (ID,Ident,source ,val,opendate,closedate,Isactive)
VALUES
(101, 'euid01' ,'File01', 'x010', '01-01-2023', '01-01-2999' ,1),
(101, 'euid02' ,'File01', 'x111', '01-01-2023', '01-01-2999' ,1),
(102, 'euid02' ,'File01', 'x222', '01-01-2023', '01-10-2024' ,0),
(102, 'euid01' ,'File01', 'x010', '01-01-2023', '01-01-2999' ,1),
(102, 'euid02' ,'File02', 'x333', '01-01-2023', '01-01-2999' ,1),
(102, 'euid02' ,'File10', 'x444', '01-01-2023', '01-10-2024' ,0)
我尝试使用合并
PROCEDURE merge_by_id (@id_from INT, @id_to INT) as
begin
declare @vFrom INT = @id_from
declare @vInto INT = @id_to
;With cte AS
(SELECT ROW_NUMBER() OVER (ORDER BY ID,identifier, source, val, opendate) AS rowid,
ID,identifier, source, val, opendate,closedate,isActive FROM MDM)
--SELECT * FROM CTE;
MERGE INTO CTE t
USING (SELECT ROW_NUMBER() OVER (ORDER BY ID,identifier, source, val, opendate) AS rw, identifier, source, val, opendate,
CASE WHEN (identifier,val) IN (SELECT identifier,val FROM MDM WHERE id = @vInto) THEN 1 END AS delete_flag
FROM MDM WHERE id = @vFrom) s
ON (t.rowid = s.rw)
WHEN MATCHED
THEN
UPDATE SET id = @vInto, closedate = getdate(), isActive = 0
DELETE WHERE delete_flag = 1;
END
一种方法似乎是您可以将具有不需要的 ID(在本例中为
UPDATE
)的所有行 102
转换为所需的 ID (101
)。然后,您使用“每组中的 TOP (1)”来 DELETE
重复的行:
--Probably should use a transaction
SET XACT_ABORT ON;
BEGIN TRANSCTION;
DECLARE @FromId int = 102, --Unwanted ID
@ToID int = 101; --Wanted ID
--Update to all the same ID
UPDATE MDM
SET ID = @ToID
FROM dbo.MDM
WHERE MDM.ID = @FromId;
--Delete duplicate rows
WITH CTE AS(
SELECT ROW_NUMBER() OVER (PARTITION BY ID, Ident, source, val, opendate, closedate, isactive ORDER BY (SELECT NULL)) AS RN
FROM dbo.MDM
WHERE ID = @ToID)
DELETE FROM CTE
WHERE RN > 1;
COMMIT;
GO
SELECT *
FROM MDM;