Unión de dos tablas con diferente número de columnas

106

Tengo dos tablas (Tabla A y Tabla B).

Estos tienen un número diferente de columnas: digamos que la Tabla A tiene más columnas.

¿Cómo puedo unir estas dos tablas y obtener nulos para las columnas que no tiene la Tabla B?

Jack Kada
fuente

Respuestas:

216

Agregue columnas adicionales como nulas para la tabla que tiene menos columnas como

Select Col1, Col2, Col3, Col4, Col5 from Table1
Union
Select Col1, Col2, Col3, Null as Col4, Null as Col5 from Table2
Kangkan
fuente
6
¿Hay alguna forma de completar un valor predeterminado para la columna Nulo?
Hans
3
@Hans: Puede hacer algo como isnull (ColumnName, 0) como ColumnName o isnull (ColumnName, '-') como ColumnName o algo similar.
Kangkan
3
Me di cuenta de que esta solución también funciona sin tener que enumerar todas las columnas. Entonces, en lugar de Select Col1, Col2, Col3, Null as Col4, Null as Col5 from Table2, también se puede hacer Select *, Null as Col4, Null as Col5 from Table2,.
Pratik Patel
Para el valor nulo, este truco funcionó para mí: 'SomeString' como DummyColumn. Básicamente, simplemente reemplaza NULL con algún valor. Esto también funcionó cuando se usó con groupby.
Saurabh Jain
8

Vine aquí y seguí la respuesta anterior. Pero la falta de coincidencia en el orden del tipo de datos provocó un error. La siguiente descripción de otra respuesta será útil.

¿Los resultados anteriores son los mismos que la secuencia de columnas en su tabla? porque Oracle es estricto en el orden de las columnas. este ejemplo a continuación produce un error:

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: la expresión debe tener el mismo tipo de datos que la expresión correspondiente

Como puede ver, la causa raíz del error está en el orden de las columnas que no coinciden, lo que implica el uso de * como especificador de lista de columnas. Este tipo de errores se pueden evitar fácilmente ingresando la lista de columnas explícitamente:

seleccione col_a, col_b, col_c de test1_1790 unión todos seleccione col_a, col_b, col_c de test2_1790; Un escenario más frecuente para este error es cuando inadvertidamente intercambias (o desplazas) dos o más columnas en la lista SELECT:

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

O si lo anterior no resuelve su problema, ¿qué tal crear un ALIAS en las columnas como esta: (la consulta no es la misma que la suya, pero el punto aquí es cómo agregar un alias en la columna).

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
fuente
Tuve que usar lo mismo, pero agregué a.col_name y b.col_name para columnas no nulas. Para columnas nulas, tuve que usar: NULL AS col_name1, NULL AS col_name2, etc
Scott R
1
nota SELECT * UNION se puede encadenar varias veces; nota DONDE se pueden usar filtros en cada cláusula SELECT
mirekphd
1

Normalmente, debe tener el mismo número de columnas cuando utiliza operadores basados ​​en conjuntos para que la respuesta de Kangkan sea ​​correcta.

SAS SQL tiene un operador específico para manejar ese escenario:

SAS (R) 9.3 Guía del usuario del procedimiento SQL

Palabra clave CORRESPONDING (CORR)

La palabra clave CORRESPONDING se usa solo cuando se especifica un operador de conjunto. CORR hace que PROC SQL coincida con las columnas de las expresiones de tabla por nombre y no por posición ordinal. Las columnas que no coinciden por nombre se excluyen de la tabla de resultados, excepto para el operador OUTER UNION.

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

Por:

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

OUTER UNION CORR

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

<=>

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

U-SQL admite un concepto similar:

UNIÓN EXTERIOR POR NOMBRE EN (*)

EXTERIOR

requiere la cláusula BY NAME y la lista ON. A diferencia de las otras expresiones de conjuntos, el esquema de salida de la UNIÓN EXTERIOR incluye tanto las columnas coincidentes como las columnas no coincidentes de ambos lados. Esto crea una situación en la que cada fila que viene de uno de los lados tiene "columnas faltantes" que solo están presentes en el otro lado. Para tales columnas, se proporcionan valores predeterminados para las "celdas faltantes". Los valores predeterminados son nulos para los tipos que aceptan valores NULL y el valor predeterminado de .Net para los tipos que no aceptan valores NULL (por ejemplo, 0 para int).

POR NOMBRE

se requiere cuando se usa con OUTER. La cláusula indica que la unión está haciendo coincidir valores no basados ​​en la posición sino por el nombre de las columnas. Si no se especifica la cláusula BY NAME, la coincidencia se realiza posicionalmente.

Si la cláusula ON incluye el símbolo "*" (se puede especificar como el último o el único miembro de la lista), entonces se permiten coincidencias de nombres adicionales más allá de las de la cláusula ON, y las columnas del resultado incluyen todas las columnas coincidentes en el orden en que están presentes en el argumento de la izquierda.

Y codigo:

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

EDITAR:

El concepto de unión externa es compatible con KQL :

tipo:

interno: el resultado tiene el subconjunto de columnas que son comunes a todas las tablas de entrada.

externo: el resultado tiene todas las columnas que ocurren en cualquiera de las entradas. Las celdas que no fueron definidas por una fila de entrada se establecen como nulas.

Ejemplo:

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;

Salida:

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

manifestación

Lukasz Szozda
fuente
¿Alguna idea de cómo lograr esto en SQL?
KetanVaghasiya
@KetanVaghasiya Hasta donde yo sé, solo SAS SQL y U-SQL admiten este concepto.
Lukasz Szozda
-1

si solo hay 1 fila, puede usar unirse

Select t1.Col1, t1.Col2, t1.Col3, t2.Col4, t2.Col5 from Table1 t1 join Table2 t2;
Sai Sai
fuente
Una unión de dos tablas de 1 fila (dos relaciones de varios conjuntos, cada una con una tupla) tendría dos filas (tuplas) en la relación resultante. En álgebra relacional (que no es SQL), el resultado de la unión puede ser una fila, aunque solo si las dos relaciones de entrada contienen una tupla idéntica, por ejemplo. autounión de una relación de una tupla.
Robert Monfera