列数が異なる2つのテーブルを結合する


106

2つのテーブルがあります(テーブルAとテーブルB)。

これらの列の数は異なります-テーブルAにもっと列があるとしましょう。

これら2つのテーブルを結合して、テーブルBにない列に対してnullを取得するにはどうすればよいですか?

回答:


216

以下のような列が少ないテーブルの場合は、余分な列をnullとして追加します

Select Col1, Col2, Col3, Col4, Col5 from Table1
Union
Select Col1, Col2, Col3, Null as Col4, Null as Col5 from Table2

6
Null列のデフォルト値を入力する方法はありますか?
Hans

3
@ハンス:isnull(ColumnName、0)as ColumnNameまたはisnull(ColumnName、 '-')as ColumnNameまたは同様のものを実行できます。
カンカン14年

3
このソリューションは、すべての列をリストしなくても機能することに気付きました。したがって、の代わりにSelect Col1, Col2, Col3, Null as Col4, Null as Col5 from Table2、を行うこともできますSelect *, Null as Col4, Null as Col5 from Table2
Pratik Patel

null値の場合、このハックは私にとってうまくいきました:DummyColumnとしての 'SomeString'。基本的には、NULLを何らかの値に置き換えるだけです。これはgroupbyで使用した場合にも機能しました。
Saurabh Jain

8

私はここに来て上記の答えに従いました。ただし、データ型の順序が一致しないため、エラーが発生しました。以下の別の回答からの説明が役に立ちます。

上記の結果は、テーブルの列のシーケンスと同じですか?オラクルは列の順序が厳密であるためです。次の例ではエラーが発生します。

create table test1_1790 (
col_a varchar2(30),
col_b number,
col_c date);

create table test2_1790 (
col_a varchar2(30),
col_c date,
col_b number);

select * from test1_1790
union all
select * from test2_1790;

ORA-01790:式には対応する式と同じデータ型が必要です

ご覧のとおり、エラーの根本的な原因は、列リスト指定子として*を使用することで暗黙的に示される列の順序の不一致にあります。このタイプのエラーは、列リストを明示的に入力することで簡単に回避できます。

test1_1790からのcol_a、col_b、col_cを選択しますunion all select test_1_1790からcol_a、col_b、col_cを選択します。このエラーのより頻繁なシナリオは、SELECTリストの2つ以上の列を誤ってスワップ(またはシフト)した場合です。

select col_a, col_b, col_c from test1_1790
union all
select col_a, col_c, col_b from test2_1790;

または、上記の方法で問題が解決しない場合は、次のように列にALIAS作成します(クエリは同じではありませんが、ここでのポイントは列にエイリアスを追加する方法です)。

SELECT id_table_a, 
       desc_table_a, 
       table_b.id_user as iUserID, 
       table_c.field as iField
UNION
SELECT id_table_a, 
       desc_table_a, 
       table_c.id_user as iUserID, 
       table_c.field as iField

同じものを使用する必要がありましたが、null以外の列にa.col_nameとb.col_nameを追加しました。null列の場合、私はNULL AS col_name1、NULL AS col_name2などを使用する必要がありました
Scott R

1
SELECT * UNIONは複数回連鎖させることができます。すべてのSELECT句でWHEREフィルターを使用できることに注意してください
mirekphd

1

通常、集合ベースの演算子を使用している場合は、同じ数の列が必要なので、Kangkanの答えは正しいです。

SAS SQLには、そのシナリオを処理するための特定の演算子があります。

SAS(R)9.3 SQLプロシージャユーザーズガイド

CORRESPONDING(CORR)キーワード

CORRESPONDINGキーワードは、集合演算子が指定されている場合にのみ使用されます。CORRを使用すると、PROC SQLは順序式ではなく名前でテーブル式の列を照合します。名前で一致しない列は、OUTER UNION演算子を除き、結果テーブルから除外されます。

SELECT * FROM tabA
OUTER UNION CORR
SELECT * FROM tabB;

ために:

+---+---+
| a | b |
+---+---+
| 1 | X |
| 2 | Y |
+---+---+

OUTER UNION CORR

+---+---+
| b | d |
+---+---+
| U | 1 |
+---+---+

<=>

+----+----+---+
| a  | b  | d |
+----+----+---+
|  1 | X  |   |
|  2 | Y  |   |
|    | U  | 1 |
+----+----+---+

U-SQLは同様の概念をサポートしています。

名前による外部ユニオン(*)

アウター

BY NAME句とONリストが必要です。他のセット式とは異なり、OUTER UNIONの出力スキーマには、両側から一致する列と一致しない列の両方が含まれます。これにより、一方の側から来る各行に、もう一方の側にのみ存在する「欠落した列」がある状況が生じます。そのような列の場合、「欠落セル」にはデフォルト値が提供されます。デフォルト値は、null許容型の場合はnullであり、null非許容型の場合は.Netのデフォルト値です(たとえば、intの場合は0)。

名前で

OUTERとともに使用する場合は必須です。この句は、ユニオンが位置ではなく列の名前に基づいて値を照合することを示しています。BY NAME句が指定されていない場合、マッチングは定位置で行われます。

ON句に「*」記号が含まれている場合(リストの最後または唯一のメンバーとして指定できます)、ON句の名前を超える追加の名前の一致が許可され、結果の列には一致するすべての列が含まれます。左の引数に存在する順序。

そしてコード:

@result =    
    SELECT * FROM @left
    OUTER UNION BY NAME ON (*) 
    SELECT * FROM @right;

編集:

外部結合の概念はKQLによってサポートされています

種類:

inner-結果には、すべての入力テーブルに共通する列のサブセットがあります。

outer-結果には、いずれかの入力で発生するすべての列があります。入力行で定義されなかったセルはnullに設定されます。

例:

let t1 = datatable(col1:long, col2:string)  
[1, "a",  
2, "b",
3, "c"];
let t2 = datatable(col3:long)
[1,3];
t1 | union kind=outer t2;

出力:

+------+------+------+
| col1 | col2 | col3 |
+------+------+------+
|    1 | a    |      |
|    2 | b    |      |
|    3 | c    |      |
|      |      |    1 |
|      |      |    3 |
+------+------+------+

デモ


SQLでこれを達成する方法はありますか?
KetanVaghasiya 2018年

@KetanVaghasiya私の知る限り、この概念をサポートしているのはSAS SQLとU-SQLだけです。
Lukasz Szozda、2018年

-1

1行のみの場合、結合を使用できます

Select t1.Col1, t1.Col2, t1.Col3, t2.Col4, t2.Col5 from Table1 t1 join Table2 t2;

2つの1行テーブルの結合(それぞれ1つのタプルを持つ2つのマルチセットリレーション)は、結果のリレーションに2つの行(タプル)を持ちます。リレーショナル代数(SQLはそうではありません)では、2つの入力リレーションに同じタプルが含まれている場合にのみ、ユニオンの結果 1行になることがあります。1組の関係の自己結合。
ロバートモンフェラ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.