Hợp nhất hai bảng với số cột khác nhau


106

Tôi có hai bảng (Bảng A và Bảng B).

Chúng có số lượng cột khác nhau - Giả sử Bảng A có nhiều cột hơn.

Làm cách nào tôi có thể kết hợp hai bảng này và lấy null cho các cột mà Bảng B không có?

Câu trả lời:


216

Thêm các cột bổ sung dưới dạng null cho bảng có ít cột hơn như

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

6
Có cách nào để điền giá trị mặc định cho cột Null không?
Hans

3
@Hans: Bạn có thể làm một cái gì đó như isnull (ColumnName, 0) as ColumnName hoặc isnull (ColumnName, '-') as ColumnName hoặc tương tự.
Kangkan

3
Tôi nhận ra rằng giải pháp này cũng hoạt động mà không cần phải liệt kê tất cả các cột. Vì vậy, thay vì Select Col1, Col2, Col3, Null as Col4, Null as Col5 from Table2, người ta cũng có thể làm Select *, Null as Col4, Null as Col5 from Table2,.
Pratik Patel

Đối với giá trị null, bản hack này phù hợp với tôi: 'SomeString' dưới dạng DummyColumn. Về cơ bản, bạn chỉ cần thay thế NULL bằng một số giá trị. Điều này cũng hoạt động khi được sử dụng với groupby.
Saurabh Jain

8

Tôi đến đây và làm theo câu trả lời ở trên. Nhưng sự không khớp trong Thứ tự của kiểu dữ liệu đã gây ra lỗi. Mô tả dưới đây từ một câu trả lời khác sẽ hữu ích.

Các kết quả trên có giống với chuỗi các cột trong bảng của bạn không? bởi vì oracle nghiêm ngặt trong thứ tự cột. ví dụ dưới đây tạo ra lỗi:

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: biểu thức phải có cùng kiểu dữ liệu với biểu thức tương ứng

Như bạn thấy, nguyên nhân gốc rễ của lỗi là trong thứ tự cột không khớp được ngụ ý bởi việc sử dụng * làm trình chỉ định danh sách cột. Loại lỗi này có thể dễ dàng tránh được bằng cách nhập danh sách cột một cách rõ ràng:

select col_a, col_b, col_c from test1_1790 union all select col_a, col_b, col_c from test2_1790; Một trường hợp thường xuyên hơn cho lỗi này là khi bạn vô tình hoán đổi (hoặc thay đổi) hai hoặc nhiều cột trong danh sách CHỌN:

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

HOẶC nếu cách trên không giải quyết được vấn đề của bạn, hãy tạo ALIAS trong các cột như thế này: (truy vấn không giống với truy vấn của bạn nhưng vấn đề ở đây là cách thêm bí danh vào cột.)

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

Tôi đã phải sử dụng cùng một thứ, nhưng tôi đã thêm a.col_name và b.col_name cho các cột không rỗng. Đối với các cột rỗng, tôi phải sử dụng: NULL AS col_name1, NULL AS col_name2, v.v.
Scott R

1
lưu ý SELECT * UNION có thể được xâu chuỗi nhiều lần; lưu ý Bộ lọc WHERE có thể được sử dụng trong mọi mệnh đề CHỌN
mirekphd

1

Thông thường, bạn cần có cùng số cột khi sử dụng toán tử dựa trên tập hợp để câu trả lời của Kangkan là đúng.

SAS SQL có toán tử cụ thể để xử lý tình huống đó:

SAS (R) 9.3 Hướng dẫn sử dụng thủ tục SQL

Từ khóa CORRESPONDING (CORR)

Từ khóa CORRESPONDING chỉ được sử dụng khi một toán tử tập hợp được chỉ định. CORR khiến PROC SQL khớp các cột trong biểu thức bảng theo tên chứ không phải theo vị trí thứ tự. Các cột không khớp theo tên sẽ bị loại trừ khỏi bảng kết quả, ngoại trừ toán tử OUTER UNION.

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

Đối với:

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

OUTER UNION CORR

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

<=>

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

U-SQL hỗ trợ khái niệm tương tự:

CÔNG ĐOÀN NGOÀI TRỜI THEO TÊN (*)

NGOÀI RA

yêu cầu mệnh đề BY NAME và danh sách BẬT. Trái ngược với các biểu thức tập hợp khác, lược đồ đầu ra của OUTER UNION bao gồm cả cột phù hợp và cột không khớp từ cả hai phía. Điều này tạo ra một tình huống trong đó mỗi hàng đến từ một trong các bên có "cột bị thiếu" chỉ có ở phía bên kia. Đối với các cột như vậy, các giá trị mặc định được cung cấp cho các "ô bị thiếu". Các giá trị mặc định là null cho các kiểu nullable và giá trị mặc định .Net cho các kiểu không nullable (ví dụ: 0 cho int).

BẰNG TÊN

là bắt buộc khi sử dụng với OUTER. Mệnh đề chỉ ra rằng liên hợp đang khớp các giá trị không dựa trên vị trí mà theo tên của các cột. Nếu mệnh đề BY NAME không được chỉ định, thì việc so khớp được thực hiện theo vị trí.

Nếu mệnh đề BẬT bao gồm ký hiệu “*” (nó có thể được chỉ định là thành viên cuối cùng hoặc thành viên duy nhất của danh sách), thì các kết quả trùng khớp tên phụ ngoài những tên trong mệnh đề BẬT được cho phép và các cột của kết quả bao gồm tất cả các cột phù hợp trong thứ tự chúng hiện diện trong đối số bên trái.

Và mã:

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

BIÊN TẬP:

Khái niệm liên minh bên ngoài được hỗ trợ bởi KQL :

Tốt bụng:

bên trong - Kết quả có tập hợp con của các cột chung cho tất cả các bảng đầu vào.

ngoài - Kết quả có tất cả các cột xuất hiện trong bất kỳ đầu vào nào. Các ô không được xác định bởi một hàng đầu vào được đặt thành null.

Thí dụ:

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;

Đầu ra:

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

bản giới thiệu


Bất kỳ ý tưởng làm thế nào để đạt được điều này trong SQL ??
KetanVaghasiya

@KetanVaghasiya Theo như tôi biết thì chỉ có SAS SQL và U-SQL hỗ trợ khái niệm này.
Lukasz Szozda

-1

nếu chỉ có 1 hàng, bạn có thể sử dụng tham gia

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

Một sự kết hợp của hai bảng 1 hàng (hai quan hệ nhiều tập, mỗi tập có một bộ) sẽ có hai hàng (bộ) trong quan hệ kết quả. Trong đại số quan hệ (mà SQL không phải) kết quả liên hợp có thể là một hàng, mặc dù chỉ khi hai quan hệ đầu vào chứa một bộ giống hệt nhau, ví dụ. tự liên kết của một quan hệ một tuple.
Robert Monfera
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.