Это связано с тем, что в Postgres CTE действуют как барьеры оптимизации. Обходной путь (с почти такой же синтаксической структурой) заключается в замене CTE на TEMP VIEW
s:
CREATE TEMP VIEW v1 AS
SELECT ta.a, ta.b, ta.c, ta.d
FROM tablea ta
WHERE a > 0 and b = 2016
;
CREATE TEMP VIEW v2 AS
SELECT a, b, c, d, e, f
FROM v1
LEFT JOIN table2 tb2 ON v1.a=tb2.a
LEFT JOIN table3 tb3 ON v1.b=tb3.b
;
SELECT * from v2;