创建视图以从多个表中获取值

时间:2018-12-17 16:23:17

标签: mysql sql oracle join

我认为编辑这篇文章并给出确切的示例毕竟更容易些。

主要思想是我需要从不同的表中获取值。

基本的主要思想是从表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)。这意味着该规则现在是针对此特定TabelA ref_num定制的,同时将新行插入到表D中(将新行ref_num保留为table_b_ref_num和新的“ modifiable_column”值)。 现在,当我要选择自定义规则时,将使用默认规则和版本(end_date IS NULL)。我必须联接表B,表C和表D。但是由于表C始终具有相同的规则,因此我只需要联接它即可获取文本值。而且我必须确保不会选择重复项。这意味着如果表C具有10条默认规则,则现在修改了一条,而自定义规则(表B)具有1条规则。然后我不得不说,从表B中选择1,从表C中选择9,但与此同时,我需要为该自定义规则加入表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 :(得分:1)

我不完全了解您的表和伪代码,但基于这种有限的理解,我的建议是从类似以下查询开始:

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;

这样,您将在第一步中看到想要的所有行。在第二步中,您应该能够使用NVLCASE来获取所需的数据。 HTH