Создать представление для получения значений из нескольких таблиц - PullRequest
0 голосов
/ 17 декабря 2018

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

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

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

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

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, чтобы получить нужные данные.НТН

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...