Создать представление для получения значений из нескольких таблиц

0

Я подумал, что легче отредактировать этот пост и привести точный пример того, что я имел в виду под этим постом.

Основная идея заключается в том, что мне нужно получить значения из разных таблиц.

По сути, основная идея состоит в том, чтобы выбрать все значения из таблицы 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 для получения результатов, как в моем примере.

  • 1
    Союз Все другое, чтобы присоединиться. Пожалуйста, просветите.
  • 0
    Не могу понять это утверждение.
Показать ещё 6 комментариев
Теги:
join

1 ответ

0

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

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 для получения нужных вам данных. НТН

  • 0
    Благодарю. Я отредактировал свой первый пост, надеюсь, теперь он более понятен.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню