The "easy button" fix is to take the definition of the CTE and use it as an inline view, in place of references to temptable
in the outer query. (This isn't necessarily the best fix, or the best way to write the query.)
Chop out the beginning of the query, this part,
WITH temptable
( column1
, column2
, column3
)
AS
( SELECT t3.column1
, t3.column2
, CASE
WHEN t3.column3 = 1 AND t2.column3 = 1 THEN 2
ELSE COALESCE(t2.column3, 0)
END AS column3
FROM table1 t1
JOIN table2 t2
ON t1.column5 = t2.column5
AND t1.column6 = t2.column6
JOIN table3 t3
ON t3.column1 = t2.column1
WHERE t1.column4 = :var1
AND t1.column6 = :var2
AND t3.column7 = 0
)
leaving just this:
SELECT a.column2
, a.column3
FROM temptable a
UNION
SELECT b.column2
, b.column3
FROM table3 b
WHERE b.column7 = -1
UNION
SELECT p.column2
, 0 AS column3
FROM table3 p
LEFT
JOIN temptable q
ON q.column2 = p.column2
WHERE q.action IS NULL
AND p.column7 = 0
(As noted in a comment on the question, the reference to action
is invalid, because there's no column named action
from temptable
.)
Then replace the references to the CTE temptable
with the inline view definition.
In the query, this would be aliaas a
and q
.
Like this:
SELECT a.column2
, a.column3
FROM -- temptable
(
SELECT t3.column1
, t3.column2
, CASE
WHEN t3.column3 = 1 AND t2.column3 = 1 THEN 2
ELSE COALESCE(t2.column3, 0)
END AS column3
FROM table1 t1
JOIN table2 t2
ON t1.column5 = t2.column5
AND t1.column6 = t2.column6
JOIN table3 t3
ON t3.column1 = t2.column1
WHERE t1.column4 = :var1
AND t1.column6 = :var2
AND t3.column7 = 0
) a
UNION
SELECT b.column2
, b.column3
FROM table3 b
WHERE b.column7 = -1
UNION
SELECT p.column2
, 0 AS column3
FROM table3 p
LEFT
JOIN -- temptable
(
SELECT t3.column1
, t3.column2
, CASE
WHEN t3.column3 = 1 AND t2.column3 = 1 THEN 2
ELSE COALESCE(t2.column3, 0)
END AS column3
FROM table1 t1
JOIN table2 t2
ON t1.column5 = t2.column5
AND t1.column6 = t2.column6
JOIN table3 t3
ON t3.column1 = t2.column1
WHERE t1.column4 = :var1
AND t1.column6 = :var2
AND t3.column7 = 0
) q
ON q.column2 = p.column2
WHERE q.action IS NULL
AND p.column7 = 0
EDIT
Oh, also... the references to :var1
and :var2
placeholders in the second occurrence of the inline view definition will probably need to be changed to be unique ... :var1b
and :var2b
(at least, this is the case with named placeholders using PDO, they have to be unique)
Copies of the values provided for for :var1
and :var2
will need to be provided for the new bind placeholders.
FOLLOWUP
Q: This query is ... hit a lot. You mention an "easy fix" but at what expense?
A: In the "easy button" fix, the two inline views a
and q
(replacement for references to the CTE) are being materialized separately. The inline view query is executed two times, and results are materialized into two separate derived tables. (The EXPLAIN output will show two separate derived tables, a
and q
).