2

UNION ALLを使用して 3 つの異なるテーブルで使用し、それらを 1 つのテーブルにマージしたかったの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 を挿入することを避けるための面倒なメカニズムを回避する方法があるかどうか疑問に思っていました。それは一度に自動的に行われましたか?

ありがとう。

4

4 に答える 4

4

要するに、いいえ。 Union結果セットをまとめるには、列の数/データ型が同じである必要があります。残りのセットを populate したい場合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
于 2015-12-14T03:36:56.770 に答える
1

ユニオンは別の選択内にある必要があります

SELECT * FROM(
    SELECT col1, col2 FROM test_table1
  UNION ALL
    SELECT col1, col2,col3 FROM test_table2
);

結果は col1 と col2 になり、一致しない列はスキップされます

于 2015-12-14T03:36:46.770 に答える
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
于 2015-12-14T07:45:13.213 に答える