I‘m sorry , the correct rewritten query should be
SELECT
"groups"."id",
"groups"."name"
FROM
"groups"
INNER JOIN "group_users" gu ON "groups"."id" = gu."group_id"
WHERE
"group_users"."user_id" = 296
AND (groups.id > 0)
AND (
groups.visibility_level IN (0, 1, 2)
OR (groups.visibility_level IN (3,4) and gu.owner)
)
ORDER BY
name ASC
subquery with predicate visibility_level = 0,1,2 can be replaced by groups.visibility_level IN (0, 1, 2) , and subquery with predicate visibility_level = 3,4 can be replaced by or (groups.visibility_level IN (3,4) and gu.owner)