I’m trying to change my code to have Oracle do all the heavy lifting. Originally, I had a function which did the following:
<!--- get common data --->
<cfquery name="getCommon">
SELECT x, NVL(SUM(y), 0) as y
FROM table_1
WHERE z between #this# and #that#
GROUP BY x
</cfquery>
<!--- place common values into a struct --->
<cfset oCommon = StructNew() >
<cfloop query="getCommon">
<cfset oCommon[x] = y >
</cfloop>
<!--- get records to loop through --->
<cfquery name="getSomething">
SELECT a, b, c/d as e from (
SELECT DISTINCT t2.a,
t2.b,
c,
sum(d)as d
FROM table_2 t2
LEFT JOIN table_3 t3
ON t2.a = t3.a
AND t2.b = t3.b
GROUP BY t2.a, t2.b, c
)
</cfquery>
<!--- loop through the results --->
<cfloop query="getSomething">
<!--- do an update to the target table if conditions are met --->
<!--- calculate my important new value --->
<cfset new_value = #getSomething.e# * #oCommon[b]# >
<!--- finally, insert my new values into the target table --->
<cfquery name="insertTarget">
INSERT INTO target_table(
a,
b,
c
)
VALUES (
#getSomething.a#,
#getSomething.b#,
#new_value#
)
</cfquery>
</cfloop>
I’ve already figured out how to use Oracle’s MERGE to replace the update statement in the loop. My problem is the SQL to replace the insert statement. I’d like to be able to calculate the new value inside the SQL… once I get that, I think I can figure out the MERGE/insert part fairly easily.
So I want to do something like:
SELECT a, b, c/d*y as e from (
SELECT DISTINCT t2.a,
t2.b,
c,
sum(d)as d,
(
SELECT y FROM (
SELECT x, NVL(SUM(y), 0) as y
FROM table_1
WHERE z between #this# and #that#
AND x = t2.a
GROUP BY x
)
)
FROM table_2 t2
LEFT JOIN table_3 t3
ON t2.a = t3.a
AND t2.b = t3.b
GROUP BY t2.a, t2.b, c
)
which, perhaps obviously, doesn’t work. Currently I get an ORA-00904: “t2″.”a”: Invalid Identifier, which isn’t surprising.
So, I basically need to figure out how to get the sum of y from table_1, correlated by x = table_2.a, into the original getSomething query.
Edit: I tried this, but it’s not quite right:
SELECT a, b, c/d*y as e from (
SELECT DISTINCT t2.a,
t2.b,
c,
sum(d)as d,
NVL(SUM(y), 0) as y
FROM table_2 t2
LEFT JOIN table_3 t3
ON t2.a = t3.a
AND t2.b = t3.b
LEFT JOIN table_1 t1
ON t1.x = t2.a
AND t1.z between #this# and #that#
GROUP BY t2.a, t2.b, c
)
You could write your query like this:
The optimizer should be able to push the predicate
t2.a = v.xinto the subquery if it is convenient (for example if there is an index ontable_1.x).