Как найти количество разных телефонов для каждого клиента и поместить клиентов (счетчики) в разные корзины в соответствии с подсчетами?

Ниже приведена таблица, в которой у меня есть customer_id и разные телефоны, которые у них есть.

customer_id     phone_number
101            123456789
102            234567891
103            345678912
102            456789123
101            567891234
104            678912345
105            789123456
106            891234567
106            912345678
106            456457234
101            655435664
107            453426782

Теперь я хочу найти customer_id и количество различных телефонных номеров.
Поэтому я использовал этот запрос:

select distinct customer_id ,count(distinct phone_number)
from customer_phone;

customer_id   no of phones
101            3
102            2
103            1
104            1
105            1
106            3
107            1

И, исходя из приведенной выше таблицы, моей конечной целью является достижение приведенного ниже вывода, который берет подсчеты и помещает их в разные корзины, а затем подсчитывает количество потребителей, попадающих в эти корзины.

Buckets no of consumers
3         2
2         1
1         4

Существует около 200 миллионов записей. Не могли бы вы объяснить эффективный способ работы над этим?


person Ishaj    schedule 22.02.2018    source источник


Ответы (2)


Используйте две агрегации:

select cnt, count(*), min(customer_id), max(customer_id)
from (select customer_id, count(distinct phone_number) as cnt
      from customer_phone
      group by customer_id
     ) c
group by cnt
order by cnt;
person Gordon Linoff    schedule 22.02.2018
comment
Спасибо, Гордон, не могли бы вы объяснить, почему нам нужно использовать min(customer_id) и max(customer_id)? - person Ishaj; 22.02.2018
comment
@Ишай. . . Вы не знаете. Я называю это гистограммой запроса гистограмм. Обычно я включаю выборочные значения, чтобы можно было изучить образцы клиентов с любым заданным количеством. - person Gordon Linoff; 22.02.2018
comment
Круто! Мне помогло. Спасибо! - person Ishaj; 22.02.2018

Вы можете использовать width_bucket для этого:

select bucket, count(*)
from (
  select width_bucket(count(distinct phone_number), 1, 10, 10) as bucket
  from customer_phone
  group by customer_id
) t
group by bucket;

width_bucket(..., 1, 10, 10) создает десять сегментов для значений от 1 до 10.

Онлайн-пример: http://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=1e6d55305570499f36383 а>

person a_horse_with_no_name    schedule 22.02.2018