#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
может быть полезно здесь, но не