Sql server 在3个表上合并所有表,每个表中的列数不同-如何高效地执行此操作

Sql server 在3个表上合并所有表,每个表中的列数不同-如何高效地执行此操作,sql-server,tsql,union-all,select-into,Sql Server,Tsql,Union All,Select Into,我想在3个不同的表上使用UNION ALL,通过使用SELECT into将它们合并到一个表中 表1、2和3分别有15、7和8列 那么,有没有一种方法可以让我使用UNION ALL,并让表2和表3对缺少的列默认为NULL,而不单独对它们进行分类 例如,我一直在做: SELECT NULL as [Company_Code], NULL as [Doc_Code], NULL as [Doc_Type], [H ID] as [Document_No] FROM [table_2] INTO

我想在3个不同的表上使用
UNION ALL
,通过使用
SELECT into
将它们合并到一个表中

表1、2和3分别有15、7和8列

那么,有没有一种方法可以让我使用
UNION ALL
,并让表2和表3对缺少的列默认为NULL,而不单独对它们进行分类

例如,我一直在做:

SELECT  NULL as [Company_Code], NULL as [Doc_Code], 
NULL as [Doc_Type], [H ID] as [Document_No] FROM [table_2] 
INTO BIG_TABLE
UNION ALL 
SELECT
[Document Company] as [Company_Code], [Document Company] as [Doc_Code], 
[Doc Type] as [Doc_Type], NULL as [Document_No]
FROM [table_3]
这样,列的数量就匹配了,我可以合并它们

然而,我想知道是否有一种方法可以避免繁琐的机制来避免为缺少的每一列插入NULL,并且这种方法是否可以一次性自动完成

谢谢。

工会应该在另一个select中
结果将是col1和col2。将跳过未匹配的列。简言之,编号。
Union
ing结果集必须具有相同的列数/数据类型。如果您想让剩余的集合填充
null
,最简单的方法就是这样做-

select col1
, col2
, col3
, col4
from tbl1

union all

select null as col1
, null as col2
, null as col3
, null as col4
from tbl2

为缺少的列设置空值的最佳方法是使用null作为列名称,您希望看到空列,如下所示:

    SELECT id as var1, mgr_id as var2,name as var3 into exp_test1 FROM
 emp123    UNION ALL
      SELECT null as employeeid, null as departmentid,null as lastname FROM employee

我仍然建议使用@iliketocode

根据您的需求生成动态列 这只是另一个选项,但完全是动态的(只需要一些时间来执行,而不是上面的答案)。为了在不定义每个列的情况下获得结果,您可以创建动态查询,通过循环自动将列添加为null

同样的问题,我面临的,由于时间短,我做了如上所述。但今天我填写了表格,给出了正确的解决方案(我当时没有这样做),并根据您的需要为您创建了一个示例,希望这能对您有所帮助

--create table t1 (col1 int , col2 int, col3 int)
--create table t2 (col1 int , col2 int, col3 int, col4 int)

--insert into t1 values (1,11,111), (2,22,222)
--insert into t2 values (1,11,111,1111), (2,22,222,null)

--Step 1 - Declaration of variable
Declare @NoOfColumnForUnion int = 5

declare @T1TableColumnList nvarchar(max) ='' ,@T2TableColumnList nvarchar(max) ='' , @colName nvarchar(500) , @test cursor

--Step 2 - Get the column list of first table i.e. t1 and store into @T1TableColumnList variable
set @test = cursor for 
                select name from syscolumns 
                where id = object_id('t1')                 

open @test
fetch next from @test into @colName
while @@fetch_status = 0 
begin
    set @T1TableColumnList = @T1TableColumnList + @colName + ','

    fetch next from @test into @colName 
end

set @T1TableColumnList = left( @T1TableColumnList , len(@T1TableColumnList )-1)

close @test
deallocate @test

--Step 3 - Get the column list of Second table i.e. t2 and store into @T2TableColumnList variable
set @test = cursor for 
                select name from syscolumns 
                where id = object_id('t2')                 

open @test
fetch next from @test into @colName
while @@fetch_status = 0 
begin
    set @T2TableColumnList = @T2TableColumnList + @colName + ','

    fetch next from @test into @colName 
end

set @T2TableColumnList = left( @T2TableColumnList , len(@T2TableColumnList )-1)

close @test
deallocate @test

--Step 4 - Check the length of column list to add null columns or remove columns
--First table check
Declare @T1lengthofColumnList int
set @T1lengthofColumnList =  (len(@T1TableColumnList) - len(replace(@T1TableColumnList, ',', '')) ) + 1

--add columns
if( @T1lengthofColumnList  < @NoOfColumnForUnion)
 Begin  
    While (@T1lengthofColumnList  < @NoOfColumnForUnion)
     Begin
        set @T1lengthofColumnList = @T1lengthofColumnList + 1
        Set @T1TableColumnList = @T1TableColumnList +  ', null col' + cast( @T1lengthofColumnList as varchar(10))
     End
 End
--remove columns
Else if( @T1lengthofColumnList  > @NoOfColumnForUnion)
 Begin
    While (@T1lengthofColumnList  > @NoOfColumnForUnion)
     Begin
        set @T1lengthofColumnList = @T1lengthofColumnList - 1       
        Set @T1TableColumnList = LEFT(@T1TableColumnList, LEN(@T1TableColumnList) - CHARINDEX(',',REVERSE(@T1TableColumnList))) 
     End
 End

--Second table check
Declare  @T2lengthofColumnList int
set @T2lengthofColumnList =  (len(@T2TableColumnList) - len(replace(@T2TableColumnList, ',', '')) ) + 1

--add columns
if( @T2lengthofColumnList  < @NoOfColumnForUnion)
 Begin  
    While (@T2lengthofColumnList  < @NoOfColumnForUnion)
     Begin
        set @T2lengthofColumnList = @T2lengthofColumnList + 1
        Set @T2TableColumnList = @T2TableColumnList +  ', null col' + cast( @T2lengthofColumnList as varchar(10))
     End
 End
--remove columns
Else if( @T2lengthofColumnList  > @NoOfColumnForUnion)
 Begin
    While (@T2lengthofColumnList  > @NoOfColumnForUnion)
     Begin
        set @T2lengthofColumnList = @T2lengthofColumnList - 1       
        Set @T2TableColumnList = LEFT(@T2TableColumnList, LEN(@T2TableColumnList) - CHARINDEX(',',REVERSE(@T2TableColumnList))) 
     End
 End

--Step 5 - create dynamic query and execute
DECLARE @template AS varchar(max)

SET @template = 'select ' + @T1TableColumnList + '  from t1 union all ' 
+ ' select ' + @T2TableColumnList + '  from t2 '

select @template 

EXEC (@template)


--drop table t1
--drop table t2
——创建表t1(col1 int、col2 int、col3 int)
--创建表t2(col1 int、col2 int、col3 int、col4 int)
--插入t1值(1,11111),(2,22222)
--插入t2值(1,111111),(2,22222,null)
--步骤1-变量的声明
声明@NoOfColumnForUnion int=5
声明@T1TableColumnList nvarchar(max)='',@T2TableColumnList nvarchar(max)='',@colName nvarchar(500),@test cursor
--步骤2-获取第一个表的列列表,即t1,并存储到@T1TableColumnList变量中
将@test=光标设置为
从syscolumns中选择名称
其中id=object\u id('t1')
打开@测试
从@test获取下一个到@colName
而@@fetch\u status=0
开始
设置@T1TableColumnList=@T1TableColumnList+@colName+,'
从@test获取下一个到@colName
结束
设置@T1TableColumnList=left(@T1TableColumnList,len(@T1TableColumnList)-1)
关闭@测试
释放@test
--步骤3-获取第二个表的列列表,即t2,并存储到@T2TableColumnList变量中
将@test=光标设置为
从syscolumns中选择名称
其中id=object\u id('t2')
打开@测试
从@test获取下一个到@colName
而@@fetch\u status=0
开始
设置@T2TableColumnList=@T2TableColumnList+@colName+,'
从@test获取下一个到@colName
结束
设置@T2TableColumnList=left(@T2TableColumnList,len(@T2TableColumnList)-1)
关闭@测试
释放@test
--步骤4-检查列列表的长度以添加空列或删除列
--第一桌检查
声明@T1lengthofColumnList int
设置@T1lengthofColumnList=(len(@T1TableColumnList)-len(replace(@T1TableColumnList,“,”)+1
--添加列
if(@T1lengthofColumnList<@NoOfColumnForUnion)
开始
While(@T1lengthofColumnList<@NoOfColumnForUnion)
开始
设置@T1lengthofColumnList=@T1lengthofColumnList+1
设置@T1TableColumnList=@T1TableColumnList+',空列'+cast(@T1lengthofColumnList为varchar(10))
终点
终点
--删除列
Else if(@T1lengthofColumnList>@NoOfColumnForUnion)
开始
而(@T1lengthofColumnList>@NoOfColumnForUnion)
开始
设置@T1lengthofColumnList=@T1lengthofColumnList-1
设置@T1TableColumnList=LEFT(@T1TableColumnList,LEN(@T1TableColumnList)-CHARINDEX(',',,REVERSE(@T1TableColumnList)))
终点
终点
--第二表检查
声明@T2lengthofColumnList int
设置@T2lengthofColumnList=(len(@T2TableColumnList)-len(replace(@T2TableColumnList,“,”)+1
--添加列
if(@T2lengthofColumnList<@NoOfColumnForUnion)
开始
While(@T2lengthofColumnList<@NoOfColumnForUnion)
开始
设置@T2lengthofColumnList=@T2lengthofColumnList+1
设置@T2TableColumnList=@T2TableColumnList+',空列'+cast(@T2lengthofColumnList为varchar(10))
终点
终点
--删除列
Else if(@T2lengthofColumnList>@NoOfColumnForUnion)
开始
而(@T2lengthofColumnList>@NoOfColumnForUnion)
开始
设置@T2lengthofColumnList=@T2lengthofColumnList-1
设置@T2TableColumnList=LEFT(@T2TableColumnList,LEN(@T2TableColumnList)-CHARINDEX(','),REVERSE(@T2TableColumnList)))
终点
终点
--步骤5-创建动态查询并执行
将@template声明为varchar(max)
SET@template='从t1 union all中选择'+@T1TableColumnList+'
+'从t2中选择'+@T2TableColumnList+'
选择@template
EXEC(@template)
--升降台t1
--升降台t2

默认情况下,它将采用第一个select语句中的列名称,因此,例如,只需从表2中选择NULL、NULL、NULL、h_id即可。检查我的答案,根据需要帮助您。我想他正在尝试将NULL填充到col3中,不要跳过它entirely@iliketocode这是正确的-我只是希望有一种更快的方法来代替为每一列键入空条目。@liketocode ya我同意你的观点,但主要目的是缩短查询时间。这是我所做的,但希望避免,因为任务的繁琐性。谢谢你,谢谢你这么多钱
--create table t1 (col1 int , col2 int, col3 int)
--create table t2 (col1 int , col2 int, col3 int, col4 int)

--insert into t1 values (1,11,111), (2,22,222)
--insert into t2 values (1,11,111,1111), (2,22,222,null)

--Step 1 - Declaration of variable
Declare @NoOfColumnForUnion int = 5

declare @T1TableColumnList nvarchar(max) ='' ,@T2TableColumnList nvarchar(max) ='' , @colName nvarchar(500) , @test cursor

--Step 2 - Get the column list of first table i.e. t1 and store into @T1TableColumnList variable
set @test = cursor for 
                select name from syscolumns 
                where id = object_id('t1')                 

open @test
fetch next from @test into @colName
while @@fetch_status = 0 
begin
    set @T1TableColumnList = @T1TableColumnList + @colName + ','

    fetch next from @test into @colName 
end

set @T1TableColumnList = left( @T1TableColumnList , len(@T1TableColumnList )-1)

close @test
deallocate @test

--Step 3 - Get the column list of Second table i.e. t2 and store into @T2TableColumnList variable
set @test = cursor for 
                select name from syscolumns 
                where id = object_id('t2')                 

open @test
fetch next from @test into @colName
while @@fetch_status = 0 
begin
    set @T2TableColumnList = @T2TableColumnList + @colName + ','

    fetch next from @test into @colName 
end

set @T2TableColumnList = left( @T2TableColumnList , len(@T2TableColumnList )-1)

close @test
deallocate @test

--Step 4 - Check the length of column list to add null columns or remove columns
--First table check
Declare @T1lengthofColumnList int
set @T1lengthofColumnList =  (len(@T1TableColumnList) - len(replace(@T1TableColumnList, ',', '')) ) + 1

--add columns
if( @T1lengthofColumnList  < @NoOfColumnForUnion)
 Begin  
    While (@T1lengthofColumnList  < @NoOfColumnForUnion)
     Begin
        set @T1lengthofColumnList = @T1lengthofColumnList + 1
        Set @T1TableColumnList = @T1TableColumnList +  ', null col' + cast( @T1lengthofColumnList as varchar(10))
     End
 End
--remove columns
Else if( @T1lengthofColumnList  > @NoOfColumnForUnion)
 Begin
    While (@T1lengthofColumnList  > @NoOfColumnForUnion)
     Begin
        set @T1lengthofColumnList = @T1lengthofColumnList - 1       
        Set @T1TableColumnList = LEFT(@T1TableColumnList, LEN(@T1TableColumnList) - CHARINDEX(',',REVERSE(@T1TableColumnList))) 
     End
 End

--Second table check
Declare  @T2lengthofColumnList int
set @T2lengthofColumnList =  (len(@T2TableColumnList) - len(replace(@T2TableColumnList, ',', '')) ) + 1

--add columns
if( @T2lengthofColumnList  < @NoOfColumnForUnion)
 Begin  
    While (@T2lengthofColumnList  < @NoOfColumnForUnion)
     Begin
        set @T2lengthofColumnList = @T2lengthofColumnList + 1
        Set @T2TableColumnList = @T2TableColumnList +  ', null col' + cast( @T2lengthofColumnList as varchar(10))
     End
 End
--remove columns
Else if( @T2lengthofColumnList  > @NoOfColumnForUnion)
 Begin
    While (@T2lengthofColumnList  > @NoOfColumnForUnion)
     Begin
        set @T2lengthofColumnList = @T2lengthofColumnList - 1       
        Set @T2TableColumnList = LEFT(@T2TableColumnList, LEN(@T2TableColumnList) - CHARINDEX(',',REVERSE(@T2TableColumnList))) 
     End
 End

--Step 5 - create dynamic query and execute
DECLARE @template AS varchar(max)

SET @template = 'select ' + @T1TableColumnList + '  from t1 union all ' 
+ ' select ' + @T2TableColumnList + '  from t2 '

select @template 

EXEC (@template)


--drop table t1
--drop table t2