Как получить количество повторяющихся значений для всех столбцов таблицы

#sql #postgresql

#sql #postgresql

Вопрос:

У меня есть такой стол, как этот,

 dept_no | employee_id 
1       | 001
1       | 002
2       | 003
2       | 004
 

Я хочу получить такие значения, как это:

 field_name | count_of_distinct_value
dept_no    | 2
employee_id| 4
 

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

Ответ №1:

 select key, count(distinct value)
from (select (jsonb_each(to_jsonb(t.*))).* from pg_class as t) as tt
group by key;
 

Это определенно не самое эффективное решение, но оно применимо для любой таблицы. Просто замените pg_class на нужное имя таблицы.

PS: Мне было очень больно предлагать это решение. Представьте таблицу со 100 миллионами строк и 100 столбцами. Затем PostgreSQL должен собрать и отсортировать промежуточные данные по 10000000000 строк.

Если вам не нужны точные цифры, а только оценочные, тогда посмотрите на pg_stats таблицу в n_distinct столбце в частности.

Ответ №2:

Вероятно, самый простой метод union all :

 select 'dept_no' as colname, count(distinct dept_no)
from t
union all
select 'employee_id' as colname, count(distinct employee_id)
from t;
 

Распаковка и агрегирование — другое возможное решение. Но это, вероятно, имеет немного худшую производительность и требует преобразования столбцов в строку (общий тип):

 select colname, count(distinct val)
from t cross join lateral
    (values ('dept_no', dept_no::text), ('employee_id', employee_id)
     ) v(colname, val)
group by colname;
 

Или лучше, за один проход:

 select
    colname,
    count_of_distinct_value
from (
    select
        count(distinct dept_no) as dept_no,
        count(distinct employee_id) as employee_id
    from t) ....
 

Комментарии:

1. когда имя таблицы изменилось, поля изменились,

2. Обычно «агрегировать, а затем отключать» более эффективно, чем «отключать, а затем агрегировать».

3. @Abelisto . , , Ваше решение в любом случае лучше; нет необходимости перечислять столбцы (именно поэтому я поддержал его).

4. Мое решение определенно плохое. Просто представьте таблицу со 100 миллионами строк и 100 столбцами. pg_stat может быть полезно здесь, но не