Кто-нибудь знает, как создавать кросс-таблицы запросов в PostgreSQL?
Например, у меня есть следующая таблица:
Section Status Count
A Active 1
A Inactive 2
B Active 4
B Inactive 5
Я бы хотел, чтобы запрос возвращал следующую кросс-таблицу:
Section Active Inactive
A 1 2
B 4 5
Это возможно?
Ответы:
Установите дополнительный модуль
tablefunc
один раз для каждой базы данных, что обеспечивает функциюcrosstab()
. Начиная с Postgres 9.1 вы можете использоватьCREATE EXTENSION
для этого:Улучшенный тестовый пример
Простая форма - не подходит для отсутствующих атрибутов
crosstab(text)
с 1 входным параметром:Возвращает:
C
: значение7
заполнено для первого столбца. Иногда такое поведение желательно, но не для этого варианта использования.Безопасная форма
crosstab(text, text)
с 2 входными параметрами:Возвращает:
Обратите внимание на правильный результат для
C
.Второй параметр может быть любым запросом , который возвращает один ряд на соответствие атрибута порядка определения столбца в конце. Часто вам нужно запросить отдельные атрибуты из базовой таблицы, например так:
Это в руководстве.
Так как в любом случае вам необходимо прописать все столбцы в списке определений столбцов (кроме предопределенных вариантов), как правило, более эффективно предоставить короткий список в выражении, как показано:
crosstabN()
VALUES
Или (не в руководстве):
Я использовал цитирование доллара, чтобы сделать его проще.
Вы даже можете выводить столбцы с разными типами данных при
crosstab(text, text)
условии, что текстовое представление столбца значения является допустимым вводом для целевого типа. Таким образом , вы можете иметь атрибуты различных видов и продукцииtext
,date
, иnumeric
т.д. для соответствующих атрибутов. В конце главыcrosstab(text, text)
руководства приведен пример кода .дБ <> скрипка здесь
Расширенные примеры
Сводка для нескольких столбцов с использованием Tablefunc - также демонстрирует упомянутые «дополнительные столбцы»
Динамическая альтернатива сводной с CASE и GROUP BY
\crosstabview
в PSQLPostgres 9.6 добавил эту мета-команду к своему интерактивному терминалу psql по умолчанию . Вы можете запустить запрос, который вы будете использовать в качестве первого
crosstab()
параметра, и передать его\crosstabview
(немедленно или на следующем шаге). Подобно:Результат, аналогичный приведенному выше, но это функция представления исключительно на стороне клиента . Входные строки обрабатываются немного по-разному, поэтому
ORDER BY
не требуется. Подробности\crosstabview
в руководстве. Внизу этой страницы есть больше примеров кода.Соответствующий ответ на dba.SE Даниэля Верите (автор функции psql):
Ранее принят ответ устарел.
Вариант функции
crosstab(text, integer)
устарел. Второйinteger
параметр игнорируется. Я цитирую текущее руководство :Ненужное литье и переименование.
Сбой, если строка не имеет всех атрибутов. См. Безопасный вариант с двумя входными параметрами выше для правильной обработки отсутствующих атрибутов.
ORDER BY
требуется в однопараметрической формеcrosstab()
. Руководство:источник
In practice the SQL query should always specify ORDER BY 1,2 to ensure that the input rows are properly ordered
Вы можете использовать
crosstab()
функцию дополнительного модуля tablefunc - которую вы должны установить один раз для каждой базы данных. Начиная с PostgreSQL 9.1 вы можете использоватьCREATE EXTENSION
для этого:В вашем случае, я думаю, это будет выглядеть примерно так:
источник
источник
sum()
, было бы лучше использоватьmin()
илиmax()
нет, иELSE
это также работаетtext
. Но это имеет несколько иной эффект, чем тотcorosstab()
, который использует только «первое» значение для каждого атрибута. Не имеет значения, пока может быть только один. Наконец, производительность тоже актуальна.crosstab()
написан на C и оптимизирован для задачи.ERROR: 42803: aggregate function calls may not be nested
Решение с агрегацией JSON:
источник
Извините, это не завершено, потому что я не могу проверить это здесь, но это может увести вас в правильном направлении. Я перевожу что-то, что я использую, что делает аналогичный запрос:
Код, из которого я работаю:
который возвращает typeID, ставку с наивысшей ценой и наименьшую запрашиваемую цену, а также разницу между ними (положительная разница будет означать, что что-то можно купить за меньшую цену, чем можно продать).
источник
Crosstab
функция доступна подtablefunc
расширением. Вам нужно будет создать это расширение один раз для базы данных.СОЗДАТЬ ПРОДЛЕНИЕ
tablefunc
;Вы можете использовать приведенный ниже код для создания сводной таблицы с использованием кросс-таблицы:
источник