我想在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]
通过这种方式,列数匹配,我可以UNION它们。
但是,我想知道是否有办法避免繁琐的机制来避免为每个丢失的列插入NULL,并且一次性自动完成?
感谢。
答案 0 :(得分:4)
简而言之,没有。 Union
结果集必须具有相同的数字/数据类型的列。如果你想让其余的集合填充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
答案 1 :(得分:1)
SELECT * FROM(
SELECT col1, col2 FROM test_table1
UNION ALL
SELECT col1, col2,col3 FROM test_table2
);
结果将是col1,col2将跳过未匹配的列
答案 2 :(得分:0)
使缺少的列无效的最佳方法是使用 null as column_name ,您要为其查看空列,如下所示:...
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
答案 3 :(得分:0)
我仍然建议使用@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