Trying to join 2 tables with an OR condition like this:
FULL JOIN table1
ON (replace(split_part(table1.contract_award_number::text, ' '::text, 2), '-'::text, ''::text)) = table2.contract_award_id
OR (btrim(replace(table1.solicitation_number::text, '-'::text, ''::text))) = table2.solicitation_id
But Postgresql is barking at me with:
FULL JOIN is only supported with merge-joinable or hash-joinable join conditions
What gives? For some reason if I add the condition:
WHERE table1.solicitation_number::text ~~ '%%'::text
the error doesn't occur, but I suspect this is fouling up the FULL JOIN result.
Thanks for any help.
It should be possible to emulate any full outer join between two tables using the following query:
SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
UNION ALL
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id
WHERE t1.id IS NULL
The first half of the union obtains the records unique to the first table, along with all overlapping records. The second half of the union obtains records particular to the second table only. Applying this pattern to your query gives:
SELECT column1, column2, column3
FROM fpds_opportunities fpds
LEFT JOIN fbo_all_opportunity_detail fbo
ON replace(split_part(fbo.contract_award_number::text, ' '::text, 2),
'-'::text, ''::text) = fpds.contract_award_id OR
btrim(replace(fbo.solicitation_number::text, '-'::text, ''::text)) = fpds.solicitation_id
UNION ALL
SELECT column1, column2, column3
FROM fpds_opportunities fpds
RIGHT JOIN fbo_all_opportunity_detail fbo
ON replace(split_part(fbo.contract_award_number::text, ' '::text, 2),
'-'::text, ''::text) = fpds.contract_award_id OR
btrim(replace(fbo.solicitation_number::text, '-'::text, ''::text)) = fpds.solicitation_id
WHERE
fpds.contract_award_id IS NULL AND fdps.solicitation_id IS NULL;
You could precompute the ugly strings in a subquery (or CTE), and JOIN with that. (this also seems handy for building & testing the query; you never get these string-things right te first time ...)
SELECT ...
FROM table2
FULL JOIN (
SELECT *
, replace(split_part(table1.contract_award_number::text, ' '::text, 2), '-'::text, ''::text) AS xca
, btrim(replace(table1.solicitation_number::text, '-'::text, ''::text)) AS xsa
FROM table1
) AS t1
ON table2.contract_award_id = t1.xca
OR table2.solicitation_id = t1.xsa
;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With