Nano Hash - криптовалюты, майнинг, программирование

Ранжировать столбцы по количеству значений

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

Я нашел способ подсчитать количество истинных значений в столбце, используя:

SELECT count(CASE WHEN col1 THEN 1 ELSE null END) as col1,
       count(CASE WHEN col2 THEN 1 ELSE null END) as col2
       ....
FROM my_table;

но у этого подхода есть две проблемы:

  1. Мне приходится вручную вводить имена столбцов
  2. Затем я должен перенести результат и упорядочить по значению

Есть ли способ сделать всю операцию одним запросом?


  • Вероятно, crosstab справится с этим. Предоставьте образец данных sqlfiddle.com и желаемый набор результатов. 13.04.2016
  • @lad2025 с crosstab вам также нужно вручную вводить имена столбцов. Если вы не используете динамический оператор, который в основном совпадает с его построением так, как представлено OP (что касается результата) 13.04.2016
  • Отредактируйте свой вопрос и предоставьте желаемые результаты 13.04.2016
  • Так у вас есть ответ? 14.04.2016

Ответы:


1

На самом деле это не кросс-таблица (или "поворот" в других СУБД), а обратная операция, контр-кросс-таблица, если хотите. Одним из элегантных приемов является выражение VALUES в соединении LATERAL.

Базовый запрос может выглядеть следующим образом:

  1. Затем я должен перенести результат и упорядочить по значению
SELECT c.col, c.ct
FROM  (
   SELECT count(col1 OR NULL) AS col1
        , count(col2 OR NULL) AS col2
          -- etc.
   FROM   tbl
   ) t
     , LATERAL (
   VALUES ('col1', col1)
        , ('col2', col2)
          -- etc.
   ) c(col, ct)
ORDER  BY 2

Это была простая часть. Другой ваш запрос сложнее:

  1. Мне приходится вручную вводить имена столбцов

Эта функция берет имя вашей таблицы и извлекает метаданные из системного каталога pg_attribute. Это динамическая реализация вышеуказанного запроса, защищенная от SQL-инъекций:

CREATE OR REPLACE FUNCTION f_true_ct(_tbl regclass)
  RETURNS TABLE (col text, ct bigint) AS
$func$
BEGIN
   RETURN QUERY EXECUTE (
   SELECT format('
      SELECT c.col, c.ct
      FROM  (SELECT %s FROM tbl) t
           , LATERAL (VALUES %s) c(col, ct)
      ORDER  BY 2 DESC'
    , string_agg (format('count(%1$I OR NULL) AS %1$I', attname), ', ')
    , string_agg (format('(%1$L, %1$I)', attname), ', ')
      )
   FROM   pg_attribute
   WHERE  attrelid = _tbl             -- valid, visible, legal table name 
   AND    attnum >= 1                 -- exclude tableoid & friends
   AND    NOT attisdropped            -- exclude dropped columns
   AND    atttypid = 'bool'::regtype  -- only character types
   );
END
$func$ LANGUAGE plpgsql;

Вызов:

SELECT * FROM f_true_ct('tbl');  -- table name optionally schema-qualified

Результат:

 col  | ct
------+---
 col1 | 3
 col3 | 2
 col2 | 1

Работает для любой таблицы для ранжирования всех boolean столбцов по их количеству true значений.

Чтобы понять параметр функции, прочтите это:

Связанные ответы с дополнительным объяснением:

13.04.2016
  • LATERAL and VALUES :) Мне всегда интересно, почему люди хотят имитировать SELECT * поведение 13.04.2016

  • 2

    Если я правильно понимаю, вы можете сделать это с помощью гигантского union all:

    select c.*
    from ((select 'col1' as which, sum(case when col1 then 1 else 0 end) as cnt from t
          ) union all
          (select 'col2' as which, sum(case when col2 then 1 else 0 end) as cnt from t
          ) union all
          . . .
         ) c
    order by cnt desc;
    

    Хотя вам все равно нужно напечатать результаты, это обходит транспозицию.

    12.04.2016
    Новые материалы

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

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..