Как добавить литералы в результат, набор результатов sql, в зависимости от того, какая таблица была объединена для создания строки?
Вопрос
У меня есть 3 таблицы, одна из которых представляет «супертип» со столбцом идентификатора.Две другие таблицы являются подтипами, каждая из которых имеет столбец идентификатора, который является внешним ключом для таблицы супертипа, а также столбец, специфичный для подтипа.
Мне нужен запрос, который возвращает все данные, а также столбец, который я могу использовать в качестве дискриминатора, сообщающего мне, из какой таблицы взята строка.
Так, например, как я могу изменить это:
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
Что возвращает мне это:
ID SUB_COL_1 SUB_COL_2
==== ========= =========
0001 value x NULL
0002 value y NULL
0003 NULL value z
Во что-то, что добавит столбец дискриминатора с некоторыми жестко запрограммированными литеральными значениями, например:
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
Мне не разрешено каким-либо образом изменять модель данных.Я также не могу выполнять постобработку путем программного тестирования NULLS постфактум.Мне нужно работать с таблицами как есть и получить точный набор результатов, показанный выше.Я использую Oracle 11g, если это имеет какое-то значение для ответа.
Решение
Можете добавить:
CASE IF S1.ID IS NULL THEN 'SUBTYPE_1' ELSE 'SUBTYPE_2' END AS DISCRIMINATOR,
в начале вашего SELECT
пункт.
Другие советы
Возможно, это то, что вы ищете... возможно, вам придется внести несколько изменений, чтобы это работало в 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
Обычно я делаю это с помощью запроса UNION.
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
Я бы, вероятно, добавил идентификатор к данным каждой таблицы в подзапросе перед присоединением к ним.
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