我认为编辑这篇文章并给出确切的示例毕竟更容易些。
主要思想是我需要从不同的表中获取值。
基本的主要思想是从表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值获取结果。
答案 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;
这样,您将在第一步中看到想要的所有行。在第二步中,您应该能够使用NVL
和CASE
来获取所需的数据。 HTH