合并两个父 > 子 table 集
Merging two parent > child table sets
我需要将两个父 > 子 table 集 merged/combined 中的数据获取到第三个父 > 子 table 中。
table 看起来像这样:
三组 table 的唯一区别是 TableC 有一个 TableType
列来帮助区分 TableA 记录和 TableB 记录之间的区别。
我的第一个想法是使用游标。下面是创建 table 结构的代码,插入一些记录,然后将数据合并在一起。效果很好,sooooo....
--Create the tables
CREATE TABLE TableA
(
ID int not null identity primary key,
Name VARCHAR(30)
);
CREATE TABLE TableAChild
(
ID int not null identity primary key,
Parent int not null,
Name VARCHAR(30),
CONSTRAINT FK_A FOREIGN KEY (Parent) REFERENCES TableA(ID)
);
CREATE TABLE TableB
(
ID int not null identity primary key,
Name VARCHAR(30)
);
CREATE TABLE TableBChild
(
ID int not null identity primary key,
Parent int not null,
Name VARCHAR(30),
CONSTRAINT FK_B FOREIGN KEY (Parent) REFERENCES TableB(ID)
);
CREATE TABLE TableC
(
ID int not null identity primary key,
TableType VARCHAR(1),
Name VARCHAR(30)
);
CREATE TABLE TableCChild
(
ID int not null identity primary key,
Parent int not null,
Name VARCHAR(30),
CONSTRAINT FK_C FOREIGN KEY (Parent) REFERENCES TableC(ID)
);
-- Insert some test records..
INSERT INTO TableA (Name) Values ('A1')
INSERT INTO TableAChild (Name, Parent) VALUES ('A1Child', SCOPE_IDENTITY())
INSERT INTO TableB (Name) Values ('B1')
INSERT INTO TableBChild (Name, Parent) VALUES ('B1Child', SCOPE_IDENTITY())
-- Needed throughout..
DECLARE @ID INT
-- Merge TableA and TableAChild into TableC and TableCChild
DECLARE TableACursor CURSOR
-- Get the primary key from TableA
FOR SELECT ID FROM TableA
OPEN TableACursor
FETCH NEXT FROM TableACursor INTO @ID
WHILE @@FETCH_STATUS = 0
BEGIN
-- INSERT INTO SELECT the parent record into TableC, being sure to specify a TableType
INSERT INTO TableC (Name, TableType) SELECT Name, 'A' FROM TableA WHERE ID = @ID
-- INSERT INTO SELECT the child record into TableCChild using the parent ID of the last row inserted (SCOPE_IDENTITY())
-- and the current record from the cursor (@ID).
INSERT INTO TableCChild(Name, Parent) SELECT Name, SCOPE_IDENTITY() FROM TableAChild WHERE Parent = @ID
FETCH NEXT FROM TableACursor INTO @ID
END;
CLOSE TableACursor
DEALLOCATE TableACursor
-- Repeat for TableB
DECLARE TableBCursor CURSOR
FOR SELECT ID FROM TableB
OPEN TableBCursor
FETCH NEXT FROM TableBCursor INTO @ID
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO TableC (Name, TableType) SELECT Name, 'B' FROM TableB WHERE ID = @ID
INSERT INTO TableCChild(Name, Parent) SELECT Name, SCOPE_IDENTITY() FROM TableBChild WHERE Parent = @ID
FETCH NEXT FROM TableBCursor INTO @ID
END;
CLOSE TableBCursor
DEALLOCATE TableBCursor
现在,我的问题:
- 我一直被告知游标不好。但我找不到另一种方法。我想知道是否有某种方法可以通过 CTE 做到这一点?
- 如果光标在这种情况下是合适的,我是怎么做到的?有没有更好的方法来做我所做的?它对我来说看起来不是很干,但我不是 SQL 专家。
最后,如果您想重新运行 上面的查询,这里有一个小脚本可以删除已创建的 table。
DROP TABLE TableAChild
DROP TABLE TableBChild
DROP TABLE TableCChild
DROP TABLE TableA
DROP TABLE TableB
DROP TABLE TableC
正确的结果应该是这样的:
您可以使用 map
table 来 link 根据一些键将旧 ID 和新 ID 组合在一起。
在我的示例中,我使用的是插入 TableC
的顺序。
- 创建一个带有标识列的映射table。
- 根据
TableA
的ID
的顺序在TableC
table中添加数据,并在map 中获取插入的id
- 使用
TableA.id
相同的顺序得到一个ROWNUMBER()
并将其与映射的标识列匹配table并更新映射中的old_id
以匹配TableA.id
与 TableC.id
.
- 使用地图插入
TableCChild
table
- 截断地图并冲洗并重复其他 tables。
示例查询
CREATE TABLE #map(id int identity,new_id int,old_id int);
INSERT INTO TableC
(
TableType,
Name
)output inserted.id into #map(new_id)
SELECT 'A',Name
FROM TableA
ORDER BY ID
update m
set m.old_id = ta.id
FROM #map m
inner join
(
select row_number()OVER(order by id asc) rn,id
from tableA
)ta on ta.rn = m.id
INSERT INTO TableCChild (Name, Parent)
SELECT Name,M.new_ID
FROM #Map M
INNER JOIN TableAChild TA ON M.old_id = TA.Parent
TRUNCATE TABLE #map
INSERT INTO TableC
(
TableType,
Name
)output inserted.id into #map(new_id)
SELECT 'B',Name
FROM TableB
ORDER BY ID
update m
set m.old_id = tb.id
FROM #map m
inner join
(
select row_number()OVER(order by id asc) rn,id
from tableB
)tb on tb.rn = m.id
INSERT INTO TableCChild (Name, Parent)
SELECT Name,M.new_ID
FROM #Map M
INNER JOIN TableBChild TB ON M.old_id = TB.Parent
DROP TABLE #Map
这是一种无需游标或其他 RBAR 类型内容即可执行此操作的方法。
ALTER TABLE TableC ADD LegacyID INT
GO
INSERT INTO TableC (TableType, Name, LegacyID)
SELECT 'A', Name, ID
FROM TableA
INSERT TableCChild
SELECT C.ID, AC.Name
FROM TableAChild AC
JOIN TableA A ON A.Id = AC.ID
JOIN TableC C ON C.LegacyID = A.ID AND C.TableType = 'A'
INSERT INTO TableC (TableType, Name, LegacyID)
SELECT 'B', Name, ID
FROM TableB
INSERT TableCChild
SELECT C.ID, AC.Name
FROM TableBChild AC
JOIN TableB A ON A.Id = AC.ID
JOIN TableC C ON C.LegacyID = A.ID AND C.TableType = 'B'
ALTER TABLE TableC DROP COLUMN LegacyID
GO
您可以使用 merge as described by Adam Machanic in Dr. OUTPUT or: How I Learned to Stop Worrying and Love the MERGE and in this 问题来获取 table 变量中新标识值和旧主键值之间的映射,以及在插入 [=17= 时使用该映射] tables.
declare @T table(ID int, IDC int);
merge dbo.TableC as C
using dbo.TableA as A
on 0 = 1
when not matched by target then
insert (TableType, Name) values('A', A.Name)
output A.ID, inserted.ID into @T(ID, IDC);
insert into dbo.TableCChild(Parent, Name)
select T.IDC, AC.Name
from dbo.TableAChild as AC
inner join @T as T
on AC.Parent = T.ID;
delete from @T;
merge dbo.TableC as C
using dbo.TableB as B
on 0 = 1
when not matched by target then
insert (TableType, Name) values('B', B.Name)
output B.ID, inserted.ID into @T(ID, IDC);
insert into dbo.TableCChild(Parent, Name)
select T.IDC, BC.Name
from dbo.TableBChild as BC
inner join @T as T
on BC.Parent = T.ID;
如果名称在表 A 中是唯一的并且在表 B 中是唯一的
,我只是写了以下内容SQL
INSERT INTO TableCChild
(
Parent,
NAME
)
SELECT tc.ID,
ta.Name
FROM TableAChild AS ta
JOIN TableA a
ON a.ID = ta.Parent
JOIN TableC AS tc
ON tc.Name = a.Name
AND tc.TableType = 'A'
UNION
SELECT tc.ID,
tb.Name
FROM TableBChild AS tb
JOIN TableB b
ON b.ID = tb.Parent
JOIN TableC AS tc
ON tc.Name = b.Name
AND tc.TableType = 'B'
如果名称不是唯一的,只有 ID 是唯一标识符,那么我会按照建议添加 LegacyId,代码如下
/* Change Table C to Have LegacyId as well and this is used to find the New Key for Inserts
CREATE TABLE TableC
(
ID INT NOT NULL IDENTITY PRIMARY KEY,
TableType VARCHAR(1),
LegacyId INT,
NAME VARCHAR(30)
);
*/
INSERT INTO TableC (Name, TableType, LegacyId)
SELECT DISTINCT NAME,
'A',
Id
FROM TableA
UNION
SELECT DISTINCT NAME,
'B',
Id
FROM TableB
INSERT INTO TableCChild
(
Parent,
NAME
)
SELECT tc.ID,
ta.Name
FROM TableAChild AS ta
JOIN TableA a
ON a.ID = ta.Parent
JOIN TableC AS tc
ON tc.LegacyId = a.Id
AND tc.TableType = 'A'
UNION
SELECT tc.ID,
tb.Name
FROM TableBChild AS tb
JOIN TableB b
ON b.ID = tb.Parent
JOIN TableC AS tc
ON tc.LegacyId = b.Id
AND tc.TableType = 'B'
我们可以通过关闭 Identity 列来实现这一点,直到我们完成插入,如下例所示。
--Create the tables
CREATE TABLE TableA
(
ID int not null identity primary key,
Name VARCHAR(30)
);
CREATE TABLE TableAChild
(
ID int not null identity primary key,
Parent int not null,
Name VARCHAR(30),
CONSTRAINT FK_A FOREIGN KEY (Parent) REFERENCES TableA(ID)
);
CREATE TABLE TableB
(
ID int not null identity primary key,
Name VARCHAR(30)
);
CREATE TABLE TableBChild
(
ID int not null identity primary key,
Parent int not null,
Name VARCHAR(30),
CONSTRAINT FK_B FOREIGN KEY (Parent) REFERENCES TableB(ID)
);
CREATE TABLE TableC
(
ID int not null identity primary key,
TableType VARCHAR(1),
Name VARCHAR(30)
);
CREATE TABLE TableCChild
(
ID int not null identity primary key,
Parent int not null,
Name VARCHAR(30),
CONSTRAINT FK_C FOREIGN KEY (Parent) REFERENCES TableC(ID)
);
-- Insert some test records..
INSERT INTO TableA (Name) Values ('A1')
INSERT INTO TableAChild (Name, Parent) VALUES ('A1Child', SCOPE_IDENTITY())
INSERT INTO TableB (Name) Values ('B1')
INSERT INTO TableBChild (Name, Parent) VALUES ('B1Child', SCOPE_IDENTITY())
SET IDENTITY_INSERT TableC ON
INSERT INTO TableC(ID, TableType, Name)
SELECT ID, 'A', Name FROM TableA
INSERT INTO TableCChild(Parent, Name)
SELECT Parent, Name FROM TableAChild
DECLARE @MAXID INT
SELECT @MAXID = MAX(ID) FROM TableC
PRINT @MAXID
SET IDENTITY_INSERT TableC ON
INSERT INTO TableC(ID, TableType, Name)
SELECT ID + @MAXID, 'B', Name FROM TableB
SET IDENTITY_INSERT TableC OFF
INSERT INTO TableCChild(Parent, Name)
SELECT Parent + @MAXID, Name FROM TableBChild
SET IDENTITY_INSERT TableC OFF
SELECT * FROM TableC
SELECT * FROM TableCChild
DROP TABLE TableAChild
DROP TABLE TableBChild
DROP TABLE TableCChild
DROP TABLE TableA
DROP TABLE TableB
DROP TABLE TableC
如果您需要在第三个 table TableC 和 TableCChild 中插入记录供以后使用,那么在这些 table 中插入数据就可以了,但是如果您只需要这个 table 数据暂时在您的存储过程中使用它,那么您也可以只使用前两个 table 来获得所需的结果。
select * from (
select a.ID,'A' as TableType,a.Name from TableA a inner join TableAChild b on a.ID=b.ID
union
select a.ID,'B' as TableType,a.Name from TableB a inner join TableBChild b on a.ID=b.ID) TableC
同样获取TableCChild
select * from
(
select b.ID,b.Parent,b.Name from TableA a inner join TableAChild b on a.ID=b.ID
union
select b.ID,b.Parent,b.Name from TableB a inner join TableBChild b on a.ID=b.ID) TableCChild
如果您必须在 TableC 和 TableCChild 中插入,则必须使用 ID 和 TableType 上的主键重新创建 TableC,并关闭 ID 列的标识。
我需要将两个父 > 子 table 集 merged/combined 中的数据获取到第三个父 > 子 table 中。
table 看起来像这样:
三组 table 的唯一区别是 TableC 有一个 TableType
列来帮助区分 TableA 记录和 TableB 记录之间的区别。
我的第一个想法是使用游标。下面是创建 table 结构的代码,插入一些记录,然后将数据合并在一起。效果很好,sooooo....
--Create the tables
CREATE TABLE TableA
(
ID int not null identity primary key,
Name VARCHAR(30)
);
CREATE TABLE TableAChild
(
ID int not null identity primary key,
Parent int not null,
Name VARCHAR(30),
CONSTRAINT FK_A FOREIGN KEY (Parent) REFERENCES TableA(ID)
);
CREATE TABLE TableB
(
ID int not null identity primary key,
Name VARCHAR(30)
);
CREATE TABLE TableBChild
(
ID int not null identity primary key,
Parent int not null,
Name VARCHAR(30),
CONSTRAINT FK_B FOREIGN KEY (Parent) REFERENCES TableB(ID)
);
CREATE TABLE TableC
(
ID int not null identity primary key,
TableType VARCHAR(1),
Name VARCHAR(30)
);
CREATE TABLE TableCChild
(
ID int not null identity primary key,
Parent int not null,
Name VARCHAR(30),
CONSTRAINT FK_C FOREIGN KEY (Parent) REFERENCES TableC(ID)
);
-- Insert some test records..
INSERT INTO TableA (Name) Values ('A1')
INSERT INTO TableAChild (Name, Parent) VALUES ('A1Child', SCOPE_IDENTITY())
INSERT INTO TableB (Name) Values ('B1')
INSERT INTO TableBChild (Name, Parent) VALUES ('B1Child', SCOPE_IDENTITY())
-- Needed throughout..
DECLARE @ID INT
-- Merge TableA and TableAChild into TableC and TableCChild
DECLARE TableACursor CURSOR
-- Get the primary key from TableA
FOR SELECT ID FROM TableA
OPEN TableACursor
FETCH NEXT FROM TableACursor INTO @ID
WHILE @@FETCH_STATUS = 0
BEGIN
-- INSERT INTO SELECT the parent record into TableC, being sure to specify a TableType
INSERT INTO TableC (Name, TableType) SELECT Name, 'A' FROM TableA WHERE ID = @ID
-- INSERT INTO SELECT the child record into TableCChild using the parent ID of the last row inserted (SCOPE_IDENTITY())
-- and the current record from the cursor (@ID).
INSERT INTO TableCChild(Name, Parent) SELECT Name, SCOPE_IDENTITY() FROM TableAChild WHERE Parent = @ID
FETCH NEXT FROM TableACursor INTO @ID
END;
CLOSE TableACursor
DEALLOCATE TableACursor
-- Repeat for TableB
DECLARE TableBCursor CURSOR
FOR SELECT ID FROM TableB
OPEN TableBCursor
FETCH NEXT FROM TableBCursor INTO @ID
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO TableC (Name, TableType) SELECT Name, 'B' FROM TableB WHERE ID = @ID
INSERT INTO TableCChild(Name, Parent) SELECT Name, SCOPE_IDENTITY() FROM TableBChild WHERE Parent = @ID
FETCH NEXT FROM TableBCursor INTO @ID
END;
CLOSE TableBCursor
DEALLOCATE TableBCursor
现在,我的问题:
- 我一直被告知游标不好。但我找不到另一种方法。我想知道是否有某种方法可以通过 CTE 做到这一点?
- 如果光标在这种情况下是合适的,我是怎么做到的?有没有更好的方法来做我所做的?它对我来说看起来不是很干,但我不是 SQL 专家。
最后,如果您想重新运行 上面的查询,这里有一个小脚本可以删除已创建的 table。
DROP TABLE TableAChild
DROP TABLE TableBChild
DROP TABLE TableCChild
DROP TABLE TableA
DROP TABLE TableB
DROP TABLE TableC
正确的结果应该是这样的:
您可以使用 map
table 来 link 根据一些键将旧 ID 和新 ID 组合在一起。
在我的示例中,我使用的是插入 TableC
的顺序。
- 创建一个带有标识列的映射table。
- 根据
TableA
的ID
的顺序在TableC
table中添加数据,并在map 中获取插入的id
- 使用
TableA.id
相同的顺序得到一个ROWNUMBER()
并将其与映射的标识列匹配table并更新映射中的old_id
以匹配TableA.id
与TableC.id
. - 使用地图插入
TableCChild
table - 截断地图并冲洗并重复其他 tables。
示例查询
CREATE TABLE #map(id int identity,new_id int,old_id int);
INSERT INTO TableC
(
TableType,
Name
)output inserted.id into #map(new_id)
SELECT 'A',Name
FROM TableA
ORDER BY ID
update m
set m.old_id = ta.id
FROM #map m
inner join
(
select row_number()OVER(order by id asc) rn,id
from tableA
)ta on ta.rn = m.id
INSERT INTO TableCChild (Name, Parent)
SELECT Name,M.new_ID
FROM #Map M
INNER JOIN TableAChild TA ON M.old_id = TA.Parent
TRUNCATE TABLE #map
INSERT INTO TableC
(
TableType,
Name
)output inserted.id into #map(new_id)
SELECT 'B',Name
FROM TableB
ORDER BY ID
update m
set m.old_id = tb.id
FROM #map m
inner join
(
select row_number()OVER(order by id asc) rn,id
from tableB
)tb on tb.rn = m.id
INSERT INTO TableCChild (Name, Parent)
SELECT Name,M.new_ID
FROM #Map M
INNER JOIN TableBChild TB ON M.old_id = TB.Parent
DROP TABLE #Map
这是一种无需游标或其他 RBAR 类型内容即可执行此操作的方法。
ALTER TABLE TableC ADD LegacyID INT
GO
INSERT INTO TableC (TableType, Name, LegacyID)
SELECT 'A', Name, ID
FROM TableA
INSERT TableCChild
SELECT C.ID, AC.Name
FROM TableAChild AC
JOIN TableA A ON A.Id = AC.ID
JOIN TableC C ON C.LegacyID = A.ID AND C.TableType = 'A'
INSERT INTO TableC (TableType, Name, LegacyID)
SELECT 'B', Name, ID
FROM TableB
INSERT TableCChild
SELECT C.ID, AC.Name
FROM TableBChild AC
JOIN TableB A ON A.Id = AC.ID
JOIN TableC C ON C.LegacyID = A.ID AND C.TableType = 'B'
ALTER TABLE TableC DROP COLUMN LegacyID
GO
您可以使用 merge as described by Adam Machanic in Dr. OUTPUT or: How I Learned to Stop Worrying and Love the MERGE and in this 问题来获取 table 变量中新标识值和旧主键值之间的映射,以及在插入 [=17= 时使用该映射] tables.
declare @T table(ID int, IDC int);
merge dbo.TableC as C
using dbo.TableA as A
on 0 = 1
when not matched by target then
insert (TableType, Name) values('A', A.Name)
output A.ID, inserted.ID into @T(ID, IDC);
insert into dbo.TableCChild(Parent, Name)
select T.IDC, AC.Name
from dbo.TableAChild as AC
inner join @T as T
on AC.Parent = T.ID;
delete from @T;
merge dbo.TableC as C
using dbo.TableB as B
on 0 = 1
when not matched by target then
insert (TableType, Name) values('B', B.Name)
output B.ID, inserted.ID into @T(ID, IDC);
insert into dbo.TableCChild(Parent, Name)
select T.IDC, BC.Name
from dbo.TableBChild as BC
inner join @T as T
on BC.Parent = T.ID;
如果名称在表 A 中是唯一的并且在表 B 中是唯一的
,我只是写了以下内容SQLINSERT INTO TableCChild
(
Parent,
NAME
)
SELECT tc.ID,
ta.Name
FROM TableAChild AS ta
JOIN TableA a
ON a.ID = ta.Parent
JOIN TableC AS tc
ON tc.Name = a.Name
AND tc.TableType = 'A'
UNION
SELECT tc.ID,
tb.Name
FROM TableBChild AS tb
JOIN TableB b
ON b.ID = tb.Parent
JOIN TableC AS tc
ON tc.Name = b.Name
AND tc.TableType = 'B'
如果名称不是唯一的,只有 ID 是唯一标识符,那么我会按照建议添加 LegacyId,代码如下
/* Change Table C to Have LegacyId as well and this is used to find the New Key for Inserts
CREATE TABLE TableC
(
ID INT NOT NULL IDENTITY PRIMARY KEY,
TableType VARCHAR(1),
LegacyId INT,
NAME VARCHAR(30)
);
*/
INSERT INTO TableC (Name, TableType, LegacyId)
SELECT DISTINCT NAME,
'A',
Id
FROM TableA
UNION
SELECT DISTINCT NAME,
'B',
Id
FROM TableB
INSERT INTO TableCChild
(
Parent,
NAME
)
SELECT tc.ID,
ta.Name
FROM TableAChild AS ta
JOIN TableA a
ON a.ID = ta.Parent
JOIN TableC AS tc
ON tc.LegacyId = a.Id
AND tc.TableType = 'A'
UNION
SELECT tc.ID,
tb.Name
FROM TableBChild AS tb
JOIN TableB b
ON b.ID = tb.Parent
JOIN TableC AS tc
ON tc.LegacyId = b.Id
AND tc.TableType = 'B'
我们可以通过关闭 Identity 列来实现这一点,直到我们完成插入,如下例所示。
--Create the tables
CREATE TABLE TableA
(
ID int not null identity primary key,
Name VARCHAR(30)
);
CREATE TABLE TableAChild
(
ID int not null identity primary key,
Parent int not null,
Name VARCHAR(30),
CONSTRAINT FK_A FOREIGN KEY (Parent) REFERENCES TableA(ID)
);
CREATE TABLE TableB
(
ID int not null identity primary key,
Name VARCHAR(30)
);
CREATE TABLE TableBChild
(
ID int not null identity primary key,
Parent int not null,
Name VARCHAR(30),
CONSTRAINT FK_B FOREIGN KEY (Parent) REFERENCES TableB(ID)
);
CREATE TABLE TableC
(
ID int not null identity primary key,
TableType VARCHAR(1),
Name VARCHAR(30)
);
CREATE TABLE TableCChild
(
ID int not null identity primary key,
Parent int not null,
Name VARCHAR(30),
CONSTRAINT FK_C FOREIGN KEY (Parent) REFERENCES TableC(ID)
);
-- Insert some test records..
INSERT INTO TableA (Name) Values ('A1')
INSERT INTO TableAChild (Name, Parent) VALUES ('A1Child', SCOPE_IDENTITY())
INSERT INTO TableB (Name) Values ('B1')
INSERT INTO TableBChild (Name, Parent) VALUES ('B1Child', SCOPE_IDENTITY())
SET IDENTITY_INSERT TableC ON
INSERT INTO TableC(ID, TableType, Name)
SELECT ID, 'A', Name FROM TableA
INSERT INTO TableCChild(Parent, Name)
SELECT Parent, Name FROM TableAChild
DECLARE @MAXID INT
SELECT @MAXID = MAX(ID) FROM TableC
PRINT @MAXID
SET IDENTITY_INSERT TableC ON
INSERT INTO TableC(ID, TableType, Name)
SELECT ID + @MAXID, 'B', Name FROM TableB
SET IDENTITY_INSERT TableC OFF
INSERT INTO TableCChild(Parent, Name)
SELECT Parent + @MAXID, Name FROM TableBChild
SET IDENTITY_INSERT TableC OFF
SELECT * FROM TableC
SELECT * FROM TableCChild
DROP TABLE TableAChild
DROP TABLE TableBChild
DROP TABLE TableCChild
DROP TABLE TableA
DROP TABLE TableB
DROP TABLE TableC
如果您需要在第三个 table TableC 和 TableCChild 中插入记录供以后使用,那么在这些 table 中插入数据就可以了,但是如果您只需要这个 table 数据暂时在您的存储过程中使用它,那么您也可以只使用前两个 table 来获得所需的结果。
select * from (
select a.ID,'A' as TableType,a.Name from TableA a inner join TableAChild b on a.ID=b.ID
union
select a.ID,'B' as TableType,a.Name from TableB a inner join TableBChild b on a.ID=b.ID) TableC
同样获取TableCChild
select * from
(
select b.ID,b.Parent,b.Name from TableA a inner join TableAChild b on a.ID=b.ID
union
select b.ID,b.Parent,b.Name from TableB a inner join TableBChild b on a.ID=b.ID) TableCChild
如果您必须在 TableC 和 TableCChild 中插入,则必须使用 ID 和 TableType 上的主键重新创建 TableC,并关闭 ID 列的标识。