Sql 如何在不重复行、不同粒度的情况下合并两个表

Sql 如何在不重复行、不同粒度的情况下合并两个表,sql,tsql,Sql,Tsql,有两个不同的表具有不同的粒度(类型和子类型),出于报告目的,我想将这两个表组合起来。 交叉连接将成倍增加行数,而我避免合并所有表,因为表有40多列 桌子 CREATE TABLE A ( SchoolID INT ,SchoolType INT ,SchoolSubtype INT ,SchoolScore INT ,LastUpdateDateTime DATETIME2 ) CREATE TABLE B ( SchoolID INT

有两个不同的表具有不同的粒度(类型和子类型),出于报告目的,我想将这两个表组合起来。 交叉连接将成倍增加行数,而我避免合并所有表,因为表有40多列

桌子

CREATE TABLE A
(
    SchoolID INT
    ,SchoolType INT
    ,SchoolSubtype INT
    ,SchoolScore INT
    ,LastUpdateDateTime DATETIME2
)


CREATE TABLE B
(
    SchoolID INT
    ,TotalStudents INT
    ,RecordedDate DATETIME2
)

INSERT INTO A (SchoolID, SchoolType, SchoolSubtype, SchoolScore, LastUpdateDateTime) 
VALUES (142, 342, 12, 98, '2019/12/01'), (142, 231, 11, 54, '2019/12/11'), (142, 231, 45, 89, '2019/12/01'), (145, 543, -1, 90, '2019/06/01')

INSERT INTO dbo.B (SchoolID, TotalStudents, RecordedDate)
VALUES (142, 82000,'2020/01/11'), (901, 78000,'2020/01/11')

SELECT *
FROM 
(
SELECT DISTINCT SchoolID, SchoolType, SchoolSubtype, 'A' AS [Source] FROM dbo.A
UNION ALL 
SELECT DISTINCT SchoolID, NULL AS SchoolType, NULL AS SchoolSubtype, 'B' AS [Source] FROM dbo.B
) AS z
    LEFT JOIN dbo.A
        ON z.SchoolID = a.SchoolID AND z.SchoolType = a.SchoolType AND z.SchoolSubtype = a.SchoolSubtype AND z.[Source] = 'A'
    LEFT JOIN dbo.B
        ON z.SchoolID = b.SchoolID AND z.[Source] = 'B'
想要的结果


如果您想防止缺少列或任何其他打印错误,您可以从
信息\u架构生成
联合所有

declare @cmd varchar(max ) = 
    'select a.SchoolID'
    +
    (select ','+ c.COLUMN_NAME
    from INFORMATION_SCHEMA.COLUMNS c
    where c.TABLE_NAME = 'A'
        and c.COLUMN_NAME != 'SchoolID'
    for xml path('')
    )
    +
    (select ', null '+ c.COLUMN_NAME
    from INFORMATION_SCHEMA.COLUMNS c
    where c.TABLE_NAME = 'B'
        and c.COLUMN_NAME != 'SchoolID'
    for xml path('')
    )
    + 
    ' from A
    union all
    select b.SchoolID'
    +
    (select ', null '+ c.COLUMN_NAME
    from INFORMATION_SCHEMA.COLUMNS c
    where c.TABLE_NAME = 'A'
        and c.COLUMN_NAME != 'SchoolID'
    for xml path('')
    )
    +
    (select ','+ c.COLUMN_NAME
    from INFORMATION_SCHEMA.COLUMNS c
    where c.TABLE_NAME = 'B'
        and c.COLUMN_NAME != 'SchoolID'
    for xml path('')
    )
    + 
    ' from B
    order by SchoolID';

exec (@cmd);

如果您可以分享您当前的查询和您面临的问题,这将更加清楚。例如,40*2列对于
UNION[ALL]
UNION ALL似乎是一个明显的选择,在每个SELECT中列出所有列,将每个表中不存在的设置为NULL。@Sujitmohanty30刚刚用我正在使用的查询更新了问题。@Serg实际上一个表有40列,B有90列。