вычисление процентов по нескольким sql таблицам - PullRequest
0 голосов
/ 19 января 2020

Есть 2 таблицы мобильных и веб

Имя таблицы: Мобильный

user_id  date        page
1        19.1.2020   pg1mob
2        13.12.2019  pg2mob 
3        14.2.2017   pg456mob

Имя таблицы: веб

user_id  date        page
15       20.1.2020   pg3web
4        23.12.2019  pg5web 
3        14.2.2017   pg652web

Мне нужно рассчитать процент пользователей, которые только посещали: мобильные, веб и оба. То есть процент пользователей, которые находятся только в мобильной таблице, только в веб-таблице и в обеих таблицах. Сумма должна быть 1.

Я пытался использовать union, но я не уверен, что это правильный путь. Как я могу рассчитать процент?

Ответы [ 2 ]

1 голос
/ 19 января 2020

Сначала получите все строки, включая столбец, указывающий, откуда эта строка, обеих таблиц с UNION ALL. Затем группа по пользователю, чтобы получить, если пользователь находится только в 1 таблице или в обеих. Наконец, используйте условное агрегирование, чтобы получить проценты:

select 
  avg(type = 1) Mobile_only,
  avg(type = 2) web_only,
  avg(type = 3) Mobile_and_web
from (
  select user_id, sum(type) type
  from (
    select distinct user_id, 1 type from Mobile      
    union all
    select distinct user_id, 2 type from web      
  ) t 
  group by t.user_id
) t

См. demo . Результаты:

| Mobile_only | web_only | Mobile_and_web |
| ----------- | -------- | -------------- |
| 0.4         | 0.4      | 0.2            |
0 голосов
/ 19 января 2020

Я бы подошел к этому, используя union all и агрегацию. Это начинается с получения информации о флаге для пользователя:

select user_id, max(is_mobile) as is_mobile, max(is_web_as is_web)
from ((select distinct user_id, 1 as is_mobile, 0 as is_web
       from mobile
      ) union all
      (select distinct user_id, 0, 1
       from web
      )
     ) u
group by user_id;

Затем объедините это далее:

select sum(is_mobile) as num_mobile,
       sum(is_web) as num_web,
       sum(is_mobile * is_web) as num_mobile_and_web,
       avg(is_mobile * (1 - is_web)) as mobile_only_rate,
       avg(is_web * (1 - is_mobile)) as web_only_rate,
       avg(is_mobile * is_web) as mobile_and_web_rate
from (select user_id, max(is_mobile) as is_mobile, max(is_web_as is_web)
      from ((select distinct user_id, 1 as is_mobile, 0 as is_web
             from mobile
            ) union all
            (select distinct user_id, 0, 1
             from web
            )
           ) u
      group by user_id
     ) u;
...