Я подумал, что легче отредактировать этот пост и привести точный пример того, что я имел в виду под этим постом.
Основная идея заключается в том, что мне нужно получить значения из разных таблиц.
По сути, основная идея состоит в том, чтобы выбрать все значения из таблицы B и таблицы C, но выбрать только значения из таблицы C, которых нет в таблице B (но в то же время мне нужно оставить присоединение к таблице C, чтобы получить значение текстового столбца). Таблица B и Таблица C имеют схожую структуру. Они оба имеют ref_num (ID) и текстовое значение. Кроме того, таблица B содержит таблицу C ref_num, поскольку при изменении сущности таблицы C ("modifiable_column") запись сохраняется в таблице B, а текстовый столбец значения "по умолчанию" берется из таблицы C.
Это что-то вроде. Допустим, у нас есть правила по умолчанию (Таблица C - всегда одни и те же значения навсегда), тогда у нас есть пользовательские правила (Таблица B). Таблица D содержит версию каждого правила с текущим значением end_date IS NULL. Значения по умолчанию имеют "modifiable_column" по умолчанию как "N", как упоминалось ранее. Теперь, допустим, я взял одно правило из таблицы C и изменил "modifiable_column" на "Y". Затем новая строка создается в таблице B (с ref_num, table_c_ref_num, text = NULL). Это означает, что это правило теперь настраивается для данного конкретного refeln TabelA, в то же время новая строка вставляется в таблицу D (с новой строкой ref_num в виде table_b_ref_num и новым значением "modifiable_column"). Теперь, когда я хочу выбрать пользовательские правила, правила и версии по умолчанию (end_date IS NULL). Я должен присоединиться к Таблице B, Таблице C и Таблице D. Но поскольку в Таблице C всегда одни и те же правила, мне нужно только присоединиться к ней, чтобы получить текстовое значение. И я должен убедиться, что не буду выбирать дубликаты. Это означает, что если в таблице C есть 10 правил по умолчанию, то теперь одно было изменено, а в пользовательских правилах (таблица B) - 1 правило. Затем я должен так сказать выбрать 1 из таблицы B и 9 из таблицы C, но в то же время мне нужно присоединить текстовое значение таблицы C для этого пользовательского правила.
У меня есть следующие таблицы, как показано ниже:
create table TableA (
ref_num INT
);
create table TableB (
ref_num INT,
text VARCHAR(100),
table_c_ref_num INT,
table_a_ref_num INT
);
create table TableC (
ref_num INT,
text VARCHAR(100)
);
create table TableD (
ref_num INT,
table_b_ref_num INT,
modfifable_column VARCHAR(1),
start_date date,
end_date date
);
Вставка начальных значений, как показано ниже:
insert into TableA (ref_num) values (1);
insert into TableC (ref_num, text) values
(1, "Text 1"),
(2, "Text 2"),
(3, "Text 3");
insert into TableB (ref_num, text, table_c_ref_num, table_a_ref_num) values
(1, NULL, 2, 1);
insert into TableD (ref_num, table_b_ref_num, modfifable_column, start_date, end_date) values
(1, 1, 'Y', now(), NULL);
Теперь я создал этот оператор select, чтобы получить желаемое поведение:
SELECT * FROM (
SELECT
tb.ref_num AS ref_num,
tb.table_a_ref_num AS table_a_ref_num,
coalesce(tc.text, tb.text),
coalesce(tc.ref_num, tb.table_c_ref_num) AS table_c_ref_num,
coalesce(td.modfifable_column, 'N') AS modfifable_column
FROM TableB tb
LEFT JOIN TableD td on td.table_b_ref_num = tb.ref_num AND td.end_date IS NULL
LEFT JOIN TableC tc on tc.ref_num = tb.table_c_ref_num
WHERE tb.table_a_ref_num = 1
) as cust
UNION ALL
SELECT * FROM (
SELECT
NULL AS ref_num,
NULL AS table_a_ref_num,
tc2.text AS text,
tc2.ref_num AS table_c_ref_num,
'N' AS modfifable_column
FROM TableC tc2
WHERE tc2.ref_num NOT IN (
SELECT
tb2.table_c_ref_num
FROM TableB tb2
LEFT JOIN TableD td on td.table_b_ref_num = tb2.ref_num AND td.end_date IS NULL
LEFT JOIN TableC tc on tc.ref_num = tb2.table_c_ref_num
WHERE tb2.table_a_ref_num = 1
)
) as def;
Я знаю, что могу превратить эти два внутренних оператора SELECT в представления, а затем объединить их, например, с UNION ALL. Больше всего меня беспокоит то, что мне нужно "жестко кодировать" table_a_ref_num = 1 в двух разных местах. Потому что я должен использовать TableA ref_num для того, чтобы получить пользовательские значения из TableB и значения по умолчанию из TableC. Потому что в конце TableA ref_num похож на пользовательские правила "этой конкретной" сущности и правила по умолчанию.
Мой вопрос: есть ли способ обернуть мое большое предложение SELECT в одно представление, где я мог бы использовать это значение TableA ref_num для получения результатов, как в моем примере.
Я не совсем понимаю ваши таблицы и псевдокод, но исходя из этого ограниченного понимания, я бы предложил, чтобы вы начали с запроса, подобного этому:
select 'ta',ta.*,'tb',tb.*,'tc_via_b',tc_via_b.*,'tc_via_a',tc_via_a.*,'td',td.*
from table_a ta
left join table_b tb on tb.table_a_ref_num = ta.ref_num
left join table_c tc_via_b on tc_via_b.ref_num = tb.table_c_ref_num
left join table_c tc_via_a on tc_via_a.ref_num = ta.ref_num
left join table_d td on td.table_b_ref_num = tb.ref_num AND td.end_date IS NULL;
Таким образом, вы увидите все нужные вам строки в качестве первого шага. На втором этапе вы сможете использовать NVL
и CASE
для получения нужных вам данных. НТН