Menggabungkan dua tabel dengan jumlah kolom berbeda

106

Saya memiliki dua tabel (Tabel A dan Tabel B).

Ini memiliki jumlah kolom yang berbeda - Katakanlah Tabel A memiliki lebih banyak kolom.

Bagaimana cara menggabungkan dua tabel ini dan mendapatkan null untuk kolom yang tidak dimiliki Tabel B?

Jack Kada
sumber

Jawaban:

215

Tambahkan kolom ekstra sebagai null untuk tabel yang memiliki lebih sedikit kolom seperti

Select Col1, Col2, Col3, Col4, Col5 from Table1
Union
Select Col1, Col2, Col3, Null as Col4, Null as Col5 from Table2
Kangkan
sumber
6
Apakah ada cara untuk mengisi nilai default untuk kolom Null?
Hans
3
@Hans: Anda dapat melakukan sesuatu seperti isnull (ColumnName, 0) sebagai ColumnName atau isnull (ColumnName, '-') sebagai ColumnName atau yang serupa.
Kangkan
3
Saya menyadari bahwa solusi ini juga berfungsi tanpa harus mencantumkan semua kolom. Jadi alih-alih Select Col1, Col2, Col3, Null as Col4, Null as Col5 from Table2, seseorang juga bisa melakukan Select *, Null as Col4, Null as Col5 from Table2,.
Pratik Patel
Untuk nilai null, peretasan ini berfungsi untuk saya: 'SomeString' sebagai DummyColumn. Pada dasarnya, Anda hanya mengganti NULL dengan beberapa nilai. Ini juga berhasil saat digunakan dengan groupby.
Saurabh Jain
8

Saya datang ke sini dan mengikuti jawaban di atas. Tetapi ketidakcocokan dalam urutan tipe data menyebabkan kesalahan. Deskripsi di bawah ini dari jawaban lain akan berguna.

Apakah hasil di atas sama dengan urutan kolom di tabel Anda? karena oracle sangat ketat dalam urutan kolom. contoh di bawah ini menghasilkan kesalahan:

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: ekspresi harus memiliki tipe data yang sama sebagai ekspresi yang sesuai

Seperti yang Anda lihat, akar penyebab kesalahan ada dalam urutan kolom yang tidak cocok yang diimplikasikan oleh penggunaan * sebagai penentu daftar kolom. Jenis kesalahan ini dapat dengan mudah dihindari dengan memasukkan daftar kolom secara eksplisit:

pilih col_a, col_b, col_c dari test1_1790 union semua pilih col_a, col_b, col_c dari test2_1790; Skenario yang lebih sering untuk kesalahan ini adalah ketika Anda secara tidak sengaja menukar (atau menggeser) dua kolom atau lebih dalam daftar PILIH:

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

ATAU jika hal di atas tidak menyelesaikan masalah Anda, bagaimana dengan membuat ALIAS di kolom seperti ini: (kueri tidak sama dengan milik Anda tetapi intinya di sini adalah cara menambahkan alias di kolom.)

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
Anand Varkey Philips
sumber
Saya harus menggunakan hal yang sama, tetapi saya menambahkan a.col_name dan b.col_name untuk kolom non-null. Untuk kolom null, saya harus menggunakan: NULL AS col_name1, NULL AS col_name2, dll
Scott R
1
catatan SELECT * UNION dapat dirantai beberapa kali; perhatikan WHERE filter dapat digunakan di setiap klausa SELECT
mirekphd
1

Biasanya Anda harus memiliki jumlah kolom yang sama saat Anda menggunakan operator berbasis himpunan sehingga jawaban Kangkan benar.

SAS SQL memiliki operator khusus untuk menangani skenario itu:

SAS (R) 9.3 Panduan Pengguna Prosedur SQL

Kata Kunci CORRESPONDING (CORR)

Kata kunci yang BENAR digunakan hanya ketika operator set ditentukan. CORR menyebabkan PROC SQL mencocokkan kolom dalam ekspresi tabel dengan nama dan bukan dengan posisi ordinal. Kolom yang tidak cocok dengan nama dikecualikan dari tabel hasil, kecuali untuk operator OUTER UNION.

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

Untuk:

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

OUTER UNION CORR

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

<=>

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

U-SQL mendukung konsep serupa:

UNI LUAR OLEH NAMA ON (*)

LUAR

membutuhkan klausa BY NAME dan daftar ON. Berbeda dengan ekspresi himpunan lainnya, skema keluaran dari OUTER UNION mencakup kolom yang cocok dan kolom yang tidak cocok dari kedua sisi. Ini menciptakan situasi di mana setiap baris yang berasal dari salah satu sisi memiliki "kolom yang hilang" yang hanya ada di sisi lain. Untuk kolom seperti itu, nilai default diberikan untuk "sel yang hilang". Nilai default adalah null untuk tipe nullable dan nilai default .Net untuk tipe non-nullable (misalnya, 0 untuk int).

DENGAN NAMA

diperlukan saat digunakan dengan OUTER. Klausul tersebut menunjukkan bahwa gabungan mencocokkan nilai bukan berdasarkan posisi tetapi berdasarkan nama kolom. Jika klausa BY NAME tidak ditentukan, pencocokan dilakukan secara posisional.

Jika klausa ON menyertakan simbol "*" (dapat ditentukan sebagai anggota terakhir atau satu-satunya dari daftar), maka nama tambahan yang cocok di luar klausa ON diperbolehkan, dan kolom hasil menyertakan semua kolom yang cocok di agar mereka ada di argumen kiri.

Dan kode:

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

EDIT:

Konsep serikat luar didukung oleh KQL :

jenis:

inner - Hasilnya memiliki subset kolom yang sama untuk semua tabel input.

luar - Hasilnya memiliki semua kolom yang muncul di salah satu input. Sel yang tidak ditentukan oleh baris masukan disetel ke nol.

Contoh:

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;

Keluaran:

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

demo

Lukasz Szozda
sumber
Tahu bagaimana mencapai ini di SQL ??
KetanVaghasiya
@KetanVasiya Setahu saya hanya SAS SQL dan U-SQL yang mendukung konsep ini.
Lukasz Szozda
-1

Jika hanya 1 baris, Anda dapat menggunakan join

Select t1.Col1, t1.Col2, t1.Col3, t2.Col4, t2.Col5 from Table1 t1 join Table2 t2;
Sai Sai
sumber
Gabungan dari dua tabel 1 baris (dua relasi multiset masing-masing dengan satu tupel) akan memiliki dua baris (tupel) dalam relasi yang dihasilkan. Dalam aljabar relasional (yang bukan SQL), hasil gabungan mungkin satu baris, meskipun hanya jika dua relasi masukan berisi tupel yang identik, misalnya. self-union dari relasi satu-tupel.
Robert Monfera