我有一个大问题(不是我写的,但我正在做一些修改)。有一点让我感到困惑的是,我在大约四个地方都有相同的COALESCE功能。有没有办法将这个问题考虑在内,可能是通过加入DUAL的选择?将其分解出来是否有性能优势?
这是稍微粗略化的查询:
select
tbl1.gid
[snip]
,COALESCE(t1_end_dt, t6_actl_end_dt,t6_calc_end_dt) perd_end_dt
,t1_end_dt
FROM tbl1
....
JOIN tbl2 ON (t2_pk = wpck_wrkr_id AND
t2_ind_1 ='Y' AND
COALESCE(t1_end_dt, t6_actl_end_dt, t6_calc_end_dt)
BETWEEN t2_strt_dt AND t2_end_dt)
JOIN tbl3 ON (t3_pk = t2_fk_t3_pk AND
COALESCE(t1_end_dt, t6_actl_end_dt, t6_calc_end_dt)
BETWEEN t3_strt_dt AND t3_end_dt)
LEFT JOIN tbl4 tbl4_a ON (tbl4_a.t4_pk = chkw_wkt_id)
.....
GROUP BY tbl1.gid
.....
,COALESCE(t1_end_dt, t6_actl_end_dt, t6_calc_end_dt)
,COALESCE(tbl4_b.t4_or_id, tbl4_a.t4_or_id, t7_or_id )
,t1_end_dt
ORDER BY perd_end_dt
请注意,我已经通过在SELECT中命名为pred_end_dt,然后在ORDER BY中通过该名称引用它来考虑其中一个COALESCE。
答案 0 :(得分:2)
您应该能够使用列别名perd_end_dt
替换GROUP BY子句中的匹配项。但是JOIN条件中的事件不能使用列别名。
这确实会对性能产生影响。我不认为加入
条件可以按照当前写入的方式使用索引。然而,
它只是JOIN条件中的一个术语,所以影响可能非常大
轻微。也就是说,涉及t2_pk
和t2_ind_1
的术语可能已经减少了行集,因此日期比较只需处理一小组。这取决于我们谈论的行数以及数据的分布方式。
分解COALESCE()
并利用索引的一种方法是创建一个冗余列,该列是该表达式的结果。每次插入或更新后,使用触发器确保它具有正确的值。然后索引列。
但就像我说的那样,它可能比它的价值更麻烦。这将是更多的工作,你应该确保这一改变将使代码更易于维护,更正确,或更快。
另一种选择是为COALESCE()
表达式定义别名
在子查询中。我无法分辨列来自哪些表,因为
你没有用表别名来限定它们。但如果我可以假设
它们都是tbl1
的所有列:
...
FROM (
SELECT COALESCE(t1_end_dt, t6_actl_end_dt, t6_calc_end_dt) perd_end_dt,
t1_fk_t2_pk
FROM tbl1) t1
JOIN tbl2
ON (tbl2.t2_pk = t1.t1_fk_t2_pk AND tbl2.t2_ind_1 = 'Y'
AND t1.perd_end_dt BETWEEN tbl2.t2_strt_dt AND tbl2.t2_end_dt)
...
答案 1 :(得分:1)
也许你可以使用with子句?
with data as
(
select COALESCE(t1_end_dt, t6_actl_end_dt,t6_calc_end_dt) perd_end_dt
, .....
, ...
from tbl1
)
select ...
from data
, ....
where ....
答案 2 :(得分:1)
你可以创建一个虚拟表
(Select Coalesce( all your stuff ....) perdEndDt
From [all your tables necessary for this one value])
并将其作为Select SQL
中的单独联接表包含在内 Select [all yr other stuff,
Z.perdEndDt
From [Other Tables Joined together]
Join
(Select Coalesce( all your stuff ....) perdEndDt,
[other columns necessary for join conditions]
From [all your tables necessary for this one value]) As Z
On [Join conditions for Z to other tables]
Where [any filter predicates]
Order By Z.perdEndDt
... etc.
答案 3 :(得分:1)
Oracle有意见吗? (它必须这样做。)如果你发现自己在许多不同的地方使用COALESCE()
表达式,那么创建一个VIEW
并使用它而不是原始表可能是值得的。在下面,将执行相同的计算,但查询的语法将更简洁,因此更清晰。
以我的思维方式,“视图”是数据库中的“表”,因为“函数”是程序中的“代码行”。每当您使用类似的逻辑找到一堆查询时,请编写一个视图,该视图会将通用逻辑分解出来并使用它。