如何从Clients表向Address表插入无重复的父母地址数据?
问题:客户表父母地址批量插入地址表的重复判断问题
表结构说明
客户表(1-01_Clients_tbl)
| AutoNo | CNR | FNC | SNC | AM1 | AM2 | AM3 | AM4 | AM5 | AF1 | AF2 | AF3 | AF4 | AF5 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 3 | 1 | FirstName | Surname | A1 | A2 | A3 | A4 | Zipcode | D | A | B | A | Zipcode |
| 4 | 2 | FirstName1 | Surname1 | C | D | E | F | Zipcode | X | Y | Z | A | Zipcode |
AM字段组代表母亲地址:AM1=地址1,AM2=地址2,AM3=城镇,AM4=城市,AM5=邮编;AF字段组代表父亲地址,结构与AM一致。
地址表(1-03_RelationsAddress_tbl)
| AddrsID | CNR | RelationID | AddressTypeID | Address1 | Address2 | Address3 | Address4 | Address5 |
|---|---|---|---|---|---|---|---|---|
| 1 | 1 | 4610 | 1 | A1 | A2 | A3 | A4 | Zipcode |
| 123 | 1 | 8653 | 1 | D | A | B | A4 | Zipcode |
关系表(Relation Table)
| RelationID | CNR | RelationTypeID | FirstName | Surname |
|---|---|---|---|---|
| 1 | 1 | 1 | First Name | Surname |
| 4610 | 1 | 2 | FirstNameParent 1 | SurnameParent1 |
| 8653 | 1 | 3 | FirstNameParent 2 | SurnameParent2 |
| 11840 | 1 | 4 | FirstNameGuarian | SurnameGuarian |
当前操作与问题
现有客户表新增了CNR=2的记录,需要将该记录中的父母地址插入到地址表中。目前分别编写了插入母亲、父亲地址的SQL,但插入母亲地址后,地址表已有该CNR值,导致父亲地址无法插入(原判断条件仅通过CNR判断重复,忽略了同一CNR对应两个不同地址的场景)。
现有插入母亲地址代码
INSERT INTO [dbo].[1-03_RelationsAddress_tbl] ([CNR] ,[AddressTypeID] ,[Address1] ,[Address2] ,[Address3] ,[Address4] ,[Address5] ,[LastUpdated] ,[UpdatedBy] ,[Active]) Select [CNR] ,1 ,[AM1] ,[AM2] ,[AM3] ,[AM4] ,[AM5] ,getdate() ,124 ,1 from dbo.[1-01_Clients_tbl] Where ([AM1] is not null or [AM2] is not null or [AM3] is not null or [AM4] is not null or [AM5] is not null) AND (dbo.[1-01_Clients_tbl].CNR NOT IN (Select [dbo].[1-03_RelationsAddress_tbl].CNR from [1-03_RelationsAddress_tbl]))
现有插入父亲地址代码
INSERT INTO [dbo].[1-03_RelationsAddress_tbl] ([CNR] ,[AddressTypeID] ,[Address1] ,[Address2] ,[Address3] ,[Address4] ,[Address5] ,[LastUpdated] ,[UpdatedBy] ,[Active]) Select [CNR] ,1 ,[AF1] ,[AF2] ,[AF3] ,[AF4] ,[AF5] ,getdate() ,124 ,1 from dbo.[1-01_Clients_tbl] Where ([AF1] is not null or [AF2] is not null or [AF3] is not null or [AF4] is not null or [AF5] is not null) AND (dbo.[1-01_Clients_tbl].CNR NOT IN (Select [dbo].[1-03_RelationsAddress_tbl].CNR from [1-03_RelationsAddress_tbl]))
解决方案
1. 修正重复判断逻辑,区分父母地址
原问题核心是仅用CNR判断重复,但同一个CNR对应父母两个不同地址,需通过CNR+RelationID的组合判断是否已存在(从关系表可知,母亲对应RelationTypeID=2,父亲对应RelationTypeID=3)。同时补充原代码遗漏的RelationID字段(地址表结构中包含该字段)。
修正后的母亲地址插入代码
INSERT INTO [dbo].[1-03_RelationsAddress_tbl] ([CNR] ,[RelationID] ,[AddressTypeID] ,[Address1] ,[Address2] ,[Address3] ,[Address4] ,[Address5] ,[LastUpdated] ,[UpdatedBy] ,[Active]) SELECT c.CNR, r.RelationID, 1, c.AM1, c.AM2, c.AM3, c.AM4, c.AM5, GETDATE(), 124, 1 FROM dbo.[1-01_Clients_tbl] c JOIN dbo.RelationTable r ON c.CNR = r.CNR AND r.RelationTypeID = 2 WHERE (c.AM1 IS NOT NULL OR c.AM2 IS NOT NULL OR c.AM3 IS NOT NULL OR c.AM4 IS NOT NULL OR c.AM5 IS NOT NULL) AND NOT EXISTS ( SELECT 1 FROM [dbo].[1-03_RelationsAddress_tbl] a WHERE a.CNR = c.CNR AND a.RelationID = r.RelationID )
修正后的父亲地址插入代码
INSERT INTO [dbo].[1-03_RelationsAddress_tbl] ([CNR] ,[RelationID] ,[AddressTypeID] ,[Address1] ,[Address2] ,[Address3] ,[Address4] ,[Address5] ,[LastUpdated] ,[UpdatedBy] ,[Active]) SELECT c.CNR, r.RelationID, 1, c.AF1, c.AF2, c.AF3, c.AF4, c.AF5, GETDATE(), 124, 1 FROM dbo.[1-01_Clients_tbl] c JOIN dbo.RelationTable r ON c.CNR = r.CNR AND r.RelationTypeID = 3 WHERE (c.AF1 IS NOT NULL OR c.AF2 IS NOT NULL OR c.AF3 IS NOT NULL OR c.AF4 IS NOT NULL OR c.AF5 IS NOT NULL) AND NOT EXISTS ( SELECT 1 FROM [dbo].[1-03_RelationsAddress_tbl] a WHERE a.CNR = c.CNR AND a.RelationID = r.RelationID )
2. 不建议截断地址表
截断地址表会直接丢失所有历史地址数据,仅适用于业务逻辑允许完全覆盖地址表的场景(比如地址表仅存储最新的父母地址,且无需保留历史)。但通常地址表需要保留所有有效地址记录,因此更推荐通过精准的组合字段判断实现增量插入。
若确实需要全量同步,可先删除对应CNR的地址记录再插入新数据,但需确认该操作不会影响其他关联业务。
内容的提问来源于stack exchange,提问作者Hariharan Iyer
相关产品推荐
相关产品推荐

