I have a large query (not written by me, but I’m making some modifications). One thing that kind of bugs me is that I’ve got the same COALESCE function in about four places. Is there a way to factor that out, possibly by joining with a select from DUAL? Is there a performance benefit to factoring it out?
Here is the query slightly bolwderized:
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
Note that I already factored out one of the COALESCEs by naming it pred_end_dt in the SELECT and then referring to it by that name in the ORDER BY.
You should be able to replace the occurrence in the GROUP BY clause with your column alias
perd_end_dt. But the occurrences in JOIN conditions cannot use the column alias.This does have an impact on performance. I don’t think the JOIN conditions can use an index the way they are written currently. However, it’s only one term in the JOIN condition, so the impact might be very slight. That is, the terms involving
t2_pkandt2_ind_1may already reduce the rowset so the date comparison only has to deal with a small set. It depends on how many rows we’re talking about and how the data is distributed.One way to factor out the
COALESCE()and take advantage of indexing would be to create a redundant column which is the result of that expression. Use triggers to make sure it has the right value after every insert or update. Then index the column.But like I said, it might be more trouble than it’s worth. It’d be more work, and you should be sure that this change would make the code more maintainable, more correct, or more speedy.
Another option would be to define an alias for the
COALESCE()expression in a subquery. I can’t tell which tables the columns come from, because you’re not qualifying them with table aliases. But if I can assume they’re all columns oftbl1: