fast-je
@fast-je
Пишу на php.

Как посчитать рекурсивно кол-во рефералов?

Всем привет!

Mysql 8

Задача такая: посчитать кол-во не всего рефералов, а кол-во рефералов у юзера на каждом уровне, до 3 уровня.

СREATE TABLE tb_users (
id int not null unsigned primary key,
username varchar(20),
id_referer int unsigned
);

CREATE INDEX fk_tree_tree ON tb_users (id_referer);

ALTER TABLE al_tree ADD CONSTRAINT fk_tree_tree
    FOREIGN KEY (id_referer) REFERENCES tb_users (id) ON UPDATE CASCADE ON DELETE CASCADE;

Сделал вот такой запрос

with recursive cte (id, id_referer, lvl) as (
  select     id,
             id_referer,
         1 lvl
  from       tb_users
  where      id_referer = 1
  union DISTINCT
  select     p.id,
             p.id_referer,
         lvl + 1
  from       tb_users p
  inner join cte
          on p.id_referer = cte.id
  where lvl < 3
)
select * from cte


Сейчас я получаю такой вывод

id id_referer lvl
2 1 1
3 1 1
.......

Мне надо получить вот такой ответ

id amount_ref_lvl_1 amount_ref_lvl_2 amount_ref_lvl_3
1 333 400 5999

То есть просто вывести кол-во рефералов у пользователя на каждом уровне.

В конце меняю select * from cte
на
select COUNT(CASE WHEN `lvl` = 1 THEN 1 END) `lvl_1`, COUNT(CASE WHEN `lvl` = 2 THEN 1 END) `lvl_2`, COUNT(CASE WHEN `lvl` = 3 THEN 1 END) `lvl_3` from cte


Правильно делаю ? Или что-то можно проще и лучше ?
  • Вопрос задан
  • 93 просмотра
Пригласить эксперта
Ответы на вопрос 1
@MaximaXXl
Я бы писал вот так:
with recursive cte (main_id, id, id_referer, lvl) as (
  select id,    
   id,
             id_referer,
         1 lvl
  from       tb_users
  where      id_referer is null
  union all
  select  main_id,   
  p.id,
             p.id_referer,
         lvl + 1
  from       tb_users p
  inner join cte
          on p.id_referer = cte.id
  where lvl < 3
)
select main_id, 
       count(case lvl when 1 then 1 end) cnt_lvl1,
       count(case lvl when 2 then 1 end) cnt_lvl2,
       count(case lvl when 3 then 1 end) cnt_lvl3
  from cte
 group by main_id


Обратите внимание на id_referer is null как точка входа и первый левел
main_id - как id первого уровня
Ну в общем разберетесь, я надеюсь ;-)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы