Łączenie dwóch tabel z różną liczbą kolumn

106

Mam dwie tabele (Tabela A i Tabela B).

Mają różną liczbę kolumn - Powiedz, że Tabela A ma więcej kolumn.

Jak mogę połączyć te dwie tabele i uzyskać wartość null dla kolumn, których nie ma w tabeli B?

Jack Kada
źródło

Odpowiedzi:

215

Dodaj dodatkowe kolumny jako puste dla tabeli mającej mniej kolumn, takich jak

Select Col1, Col2, Col3, Col4, Col5 from Table1
Union
Select Col1, Col2, Col3, Null as Col4, Null as Col5 from Table2
Kangkan
źródło
6
Czy istnieje sposób na wypełnienie domyślnej wartości kolumny Null?
Hans
3
@Hans: Możesz zrobić coś takiego jak isnull (ColumnName, 0) jako ColumnName lub isnull (ColumnName, „-”) jako ColumnName lub coś podobnego.
Kangkan
3
Zdałem sobie sprawę, że to rozwiązanie działa również bez konieczności wypisywania wszystkich kolumn. Zamiast więc Select Col1, Col2, Col3, Null as Col4, Null as Col5 from Table2, można również zrobić Select *, Null as Col4, Null as Col5 from Table2.
Pratik Patel,
Dla wartości null ten hack zadziałał dla mnie: „SomeString” jako DummyColumn. Zasadniczo po prostu zastępujesz NULL jakąś wartością. Działało to również w przypadku korzystania z funkcji Groupby.
Saurabh Jain
8

Przyszedłem tutaj i zastosowałem się do powyższej odpowiedzi. Jednak niezgodność w kolejności typów danych spowodowała błąd. Przyda się poniższy opis z innej odpowiedzi.

Czy powyższe wyniki są takie same, jak sekwencja kolumn w tabeli? ponieważ wyrocznia jest surowa w kolejności kolumn. poniższy przykład generuje błąd:

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: wyrażenie musi mieć ten sam typ danych, co odpowiadające mu wyrażenie

Jak widać, główną przyczyną błędu jest niezgodna kolejność kolumn, która jest implikowana przez użycie * jako specyfikatora listy kolumn. Tego typu błędów można łatwo uniknąć, wpisując jawnie listę kolumn:

wybierz col_a, col_b, col_c z test1_1790 union wszystkie wybierz col_a, col_b, col_c z test2_1790; Częstszym scenariuszem tego błędu jest przypadkowa zamiana (lub przesunięcie) dwóch lub więcej kolumn na liście SELECT:

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

LUB jeśli powyższe nie rozwiąże problemu, co powiesz na utworzenie ALIAS w kolumnach takich jak ta: (zapytanie nie jest takie samo jak twoje, ale chodzi o to, jak dodać alias w kolumnie).

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
źródło
Musiałem użyć tego samego, ale dodałem a.col_name i b.col_name dla kolumn niezerowych. W przypadku kolumn o wartości null musiałem użyć: NULL AS nazwa_kolumny1, NULL AS nazwa_kolumny2 itp.
Scott R
1
uwaga SELECT * UNION można łączyć wiele razy; uwaga, GDZIE filtry mogą być używane w każdej klauzuli SELECT
mirekphd
1

Zwykle musisz mieć taką samą liczbę kolumn, gdy używasz operatorów opartych na zbiorach, aby odpowiedź Kangkana była poprawna.

SAS SQL ma określonego operatora do obsługi tego scenariusza:

Instrukcja obsługi procedury SAS (R) 9.3 SQL

Słowo kluczowe CORRESPONDING (CORR)

Słowo kluczowe CORRESPONDING jest używane tylko wtedy, gdy określono operator zestawu. CORR powoduje, że PROC SQL dopasowuje kolumny w wyrażeniach tabeli według nazwy, a nie według pozycji porządkowej. Kolumny, które nie pasują według nazwy, są wykluczane z tabeli wynikowej, z wyjątkiem operatora UNER UNION.

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

Dla:

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

OUTER UNION CORR

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

<=>

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

U-SQL obsługuje podobną koncepcję:

UNIA ZEWNĘTRZNA WEDŁUG NAZWY (*)

ZEWNĘTRZNY

wymaga klauzuli BY NAME i listy ON. W przeciwieństwie do innych wyrażeń zestawu, schemat wyjściowy UNER OUTER zawiera zarówno pasujące kolumny, jak i niezgodne kolumny z obu stron. Stwarza to sytuację, w której każdy wiersz wychodzący z jednej strony ma „brakujące kolumny”, które są obecne tylko po drugiej stronie. W przypadku takich kolumn podawane są wartości domyślne dla „brakujących komórek”. Wartości domyślne to null dla typów dopuszczających wartość null, a wartość domyślna .Net dla typów nie dopuszczających wartości null (np. 0 dla typu int).

WG NAZWY

jest wymagany, gdy jest używany z OUTER. Klauzula wskazuje, że Unia dopasowuje wartości nie na podstawie pozycji, ale według nazwy kolumn. Jeśli nie określono klauzuli BY NAME, dopasowywanie odbywa się pozycyjnie.

Jeśli klauzula ON zawiera symbol „*” (może być określony jako ostatni lub jedyny element listy), to dozwolone są dodatkowe dopasowania nazw poza tymi w klauzuli ON, a kolumny wyniku zawierają wszystkie pasujące kolumny w kolejność są obecne w lewym argumencie.

I kod:

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

EDYTOWAĆ:

Koncepcja unii zewnętrznej jest obsługiwana przez KQL :

uprzejmy:

wewnętrzna - wynik zawiera podzbiór kolumn, które są wspólne dla wszystkich tabel wejściowych.

zewnętrzny - wynik zawiera wszystkie kolumny, które występują w dowolnym z danych wejściowych. Komórki, które nie zostały zdefiniowane przez wiersz wejściowy, mają wartość null.

Przykład:

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;

Wynik:

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

próbny

Łukasz Szozda
źródło
Każdy pomysł, jak to osiągnąć w SQL?
KetanVaghasiya
@KetanVaghasiya O ile wiem, tylko SAS SQL i U-SQL obsługują tę koncepcję.
Łukasz Szozda
-1

jeśli tylko 1 wiersz, możesz użyć złączenia

Select t1.Col1, t1.Col2, t1.Col3, t2.Col4, t2.Col5 from Table1 t1 join Table2 t2;
Sai Sai
źródło
Suma dwóch 1-wierszowych tabel (dwóch relacji multiset, każda z jedną krotką) miałaby dwa wiersze (krotki) w wynikowej relacji. W algebrze relacyjnej (której SQL nie jest) wynikiem unii może być jeden wiersz, ale tylko wtedy, gdy dwie relacje wejściowe zawierały identyczną krotkę, np. samozwiązanie relacji jednej krotki.
Robert Monfera,