Code:
select
p.productid
,i.productname
,p.price
from
products p
inner join
productinfo i
on
p.productid = i.productid
and
(
i.languageid = 2
or
(
(select count(*) from productinfo i2 where i2.productid = p.productid and i2.languageid = 2) = 0
and
i.languageid = 1
)
)
;
I don't know if logical operations are done like in C/C++. If yes, when a product have the languageid = 2, beeing an OR comparison, it is not needed to execute the second part, since the result is already know (true). In C we can trust that in this case the right part of the expression will not be executed.
If doesn't have a product with languageid = 2, then it will be necessariy to test the second part of the expression.
If Postgres execute both, in any case, it is just a performance question, but will work too. (will work? you tell me. :-) )