¿Cómo se pone literales en el resultado de un conjunto de resultados SQL basado en la tabla que se unió para crear la fila?
Pregunta
Tengo 3 tablas, una que representa un "supertipo", con una columna de ID. otras dos mesas son cada uno de los subtipos, con una columna de ID que es una clave externa a la tabla supertipo, además de una columna de subtipo específico.
Quiero una consulta que devuelve todos los datos, así como una columna que pueda usar como un discriminador que me dice lo que la tabla la fila de procedencia.
Así, por ejemplo, cómo puedo modificar esto:
SELECT * from SUPER S
left outer join SUB_1 S1 on S.ID = S1.ID
left outer join SUB_2 S2 on S.ID = S2.ID
Lo que me devuelve este:
ID SUB_COL_1 SUB_COL_2
==== ========= =========
0001 value x NULL
0002 value y NULL
0003 NULL value z
en algo que agregará una columna discriminadora con algunos valores literales codificadas de forma rígida, como esto:
ID DISCRIMINATOR SUB_COL_1 SUB_COL_2
==== ============= ========= =========
0001 SUBTYPE_1 value x NULL
0002 SUBTYPE_1 value y NULL
0003 SUBTYPE_2 NULL value z
No se me permite modificar el modelo de datos de ninguna manera. Asimismo, no puede hacer ningún post-procesamiento mediante pruebas de programación para NULLS después del hecho. Necesito trabajar con las tablas como es, y producir el conjunto de resultados exacta se muestra arriba. Estoy utilizando Oracle 11g, si es que tiene alguna diferencia en la respuesta.
Solución
Puede añadir:
CASE IF S1.ID IS NULL THEN 'SUBTYPE_1' ELSE 'SUBTYPE_2' END AS DISCRIMINATOR,
en el inicio de su cláusula de SELECT
.
Otros consejos
Tal vez esto es lo que busca ... puede que tenga que hacer algunos cambios para que funcione en Oracle.
SELECT case coalesce(SUB_COL_1,'') when '' then 'SUBTYPE_2' else 'SUBTYPE_1' end, * from SUPER S
left outer join SUB_1 S1 on S.ID = S1.ID
left outer join SUB_2 S2 on S.ID = S2.ID
Yo suelo hacer esto con una consulta de unión
Select S.ID, SUBTYPE_1 as DISCRIMINATOR, S1field1 as SUB_COL_1, null as SUB_COL_2
from SUPER S
join SUB_1 S1 on S.ID = S1.ID
union all
Select S.ID, SUBTYPE_2 as DISCRIMINATOR, null as SUB_COL_1, S2.field1 as SUB_COL_2
from SUPER S
join SUB_2 S2 on S.ID = S2.ID
probablemente me añadir el identificador a los datos de cada tabla en una subconsulta antes de unirse a él.
SELECT * from
(select *, 'SUPER' as DISCRIMINATOR from SUPER ) S
left outer join
(select *, 'SUBTYPE1' as DISCRIMINATOR from SUB_1 ) S1
on S.ID = S1.ID
left outer join
(select *, 'SUBTYPE1' as DISCRIMINATOR from SUB_2 ) S2
on S.ID = S2.ID