Почему бы не использовать or
?
SELECT f.*
FROM forms f
WHERE EXISTS (SELECT *
FROM jsonb_each_text(f.column_a) as e(ky,val)
WHERE e.val = 'mail@example.com'
) OR
EXISTS (SELECT *
FROM jsonb_each_text(f.column_b) as e(ky,val)
WHERE e.val = 'mail@example.com'
) OR
. . .
Предположительно, это также устраняет необходимость удаления дубликатов, поэтому запрос также должен выполняться быстрее.
РЕДАКТИРОВАТЬ:
Если вам нужны источники, вы можете использовать коррелированные подзапросы:
SELECT f.*
FROM (SELECT f.*,
EXISTS (SELECT *
FROM jsonb_each_text(f.column_a) as e(ky,val)
WHERE e.val = 'mail@example.com'
) as in_column_a,
EXISTS (SELECT *
FROM jsonb_each_text(f.column_b) as e(ky,val)
WHERE e.val = 'mail@example.com'
) as in_column_b,
. . .
FROM forms f
)
WHERE in_column_a OR in_column_b OR . . .
Это не так эффективно, потому что оно не закорачивает оценку, когда находит совпадение. С другой стороны, в нем перечислены все столбцы, которые соответствуют.