Объединение двух таблиц с разным количеством столбцов - PullRequest
81 голосов
/ 22 февраля 2010

У меня есть две таблицы (Таблица A и Таблица B).

У них разное количество столбцов - скажем, в таблице A больше столбцов.

Как я могу объединить эти две таблицы и получить нулевое значение для столбцов, которых нет в таблице B?

Ответы [ 4 ]

174 голосов
/ 22 февраля 2010

Добавить дополнительные столбцы как ноль для таблицы, имеющей меньше столбцов, таких как

Select Col1, Col2, Col3, Col4, Col5 from Table1
Union
Select Col1, Col2, Col3, Null as Col4, Null as Col5 from Table2
6 голосов
/ 23 ноября 2016

Я пришел сюда и последовал за ответом выше. Но несоответствие в порядке типов данных вызвало ошибку. Приведенное ниже описание из другого ответа пригодится.

Результаты выше совпадают с последовательностью столбцов в вашей таблице? потому что оракул строг в порядках столбцов. этот пример ниже выдает ошибку:

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: выражение должно иметь тот же тип данных, что и соответствующее выражение

Как видите, основная причина ошибки заключается в несоответствии порядка столбцов, что подразумевается использованием * в качестве спецификатора списка столбцов. Этого типа ошибок легко избежать, введя список столбцов явно:

выберите col_a, col_b, col_c из test1_1790 объединить всех выберите col_a, col_b, col_c из test2_1790; Более частый сценарий этой ошибки - случайная замена (или смещение) двух или более столбцов в списке SELECT:

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
0 голосов
/ 26 сентября 2018

Обычно вам нужно иметь одинаковое количество столбцов, когда вы используете операторы на основе множеств, поэтому Кангканский ответ правильный.

SAS SQL имеет специальный оператор для обработки этого сценария:

SAS (R) 9.3 Руководство пользователя процедуры SQL

КОРРЕСПОНДИНГ (CORR) Ключевое слово

Ключевое слово CORRESPONDING используется только в том случае, если указан оператор set. 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 поддерживает аналогичную концепцию:

Внешний союз по имени (*)

OUTER

требуется предложение BY NAME и список ON. В отличие от других выражений набора, выходная схема OUTER UNION включает в себя как совпадающие столбцы, так и несовпадающие столбцы с обеих сторон. Это создает ситуацию, когда в каждой строке, приходящей с одной из сторон, есть «пропущенные столбцы», которые присутствуют только на другой стороне. Для таких столбцов значения по умолчанию предоставляются для «отсутствующих ячеек». Значения по умолчанию равны нулю для типов, допускающих значение NULL, и значения по умолчанию .Net для типов, не допускающих значения NULL (например, 0 для типа int).

ПО ИМЕНЕ

требуется при использовании с OUTER. Предложение указывает, что объединение сопоставляет значения не на основе позиции, а по имени столбцов. Если предложение BY NAME не указано, сопоставление выполняется позиционно.

Если предложение ON содержит символ «*» (он может быть указан как последний или единственный элемент списка), тогда допускаются дополнительные совпадения имен, помимо тех, которые указаны в предложении ON, а столбцы результата включают все соответствующие столбцы в порядке их присутствия в левом аргументе.

и код:

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

EDIT:

Концепция внешнего объединения поддерживается KQL :

вид:

inner - результат имеет подмножество столбцов, общих для всех входных таблиц.

external - У результата есть все столбцы, которые встречаются в любом из входных данных. Ячейки, которые не были определены входной строкой, устанавливаются в ноль.

Пример:

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 |
+------+------+------+

демо

0 голосов
/ 26 сентября 2017

если только 1 строка, вы можете использовать join

Select t1.Col1, t1.Col2, t1.Col3, t2.Col4, t2.Col5 from Table1 t1 join Table2 t2;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...