drop function if exists get_referers(param_user_id bigint, param_user_bm_id smallint) cascade; create function get_referers(param_user_id bigint, param_user_bm_id smallint) returns table ( referer_id bigint, referer_level integer ) as $end$ begin return query with recursive tree as ( select users.referer_id as referer_id, ( select count(*) % 5 + 1 from user_bms where user_bms.user_id=users.referer_id and user_bms.bm_id=param_user_bm_id )::integer as referer_level from users where users.user_id = param_user_id union select users.referer_id as referer_id, tree.referer_level::integer - case when user_bms is null then 0 else 1 end as referer_level from users left join user_bms on user_bms.user_id = users.user_id and user_bms.bm_id = param_user_bm_id join tree on tree.referer_id = users.user_id and users.user_id != users.referer_id where tree.referer_level - case when user_bms is null then 0 else 1 end > 0 ) select * from tree order by referer_level limit 1; end; $end$ language plpgsql; select * from get_referers(1122::bigint, 1::smallint);