Встановіть додатковий модуль tablefunc один раз у базі даних, що забезпечує функцію crosstab(). Оскільки Postgres 9.1 ви можете використовувати CREATE EXTENSIONдля цього:
CREATE EXTENSION IF NOT EXISTS tablefunc;
Поліпшена тестова справа
CREATE TABLE tbl (
section text
, status text
, ct integer -- "count" is a reserved word in standard SQL
);
INSERT INTO tbl VALUES
('A', 'Active', 1), ('A', 'Inactive', 2)
, ('B', 'Active', 4), ('B', 'Inactive', 5)
, ('C', 'Inactive', 7); -- ('C', 'Active') is missing
Проста форма - не підходить для відсутніх атрибутів
crosstab(text)з 1 вхідним параметром:
SELECT *
FROM crosstab(
'SELECT section, status, ct
FROM tbl
ORDER BY 1,2' -- needs to be "ORDER BY 1,2" here
) AS ct ("Section" text, "Active" int, "Inactive" int);
Повернення:
Розділ | Активний | Неактивний
--------- + -------- + ----------
А | 1 | 2
Б | 4 | 5
C | 7 | - !!
- Не потрібно кастингу та перейменування.
- Зверніть увагу на неправильний результат для
C: значення 7заповнюється для першого стовпця. Іноді така поведінка є бажаною, але не для цього випадку використання.
- Проста форма також обмежена рівно трьома стовпцями у наданому вхідному запиті: ім'я рядка , категорія , значення . Немає місця для додаткових стовпців, як, наприклад, в 2-х параметрах нижче.
Безпечна форма
crosstab(text, text)з 2 вхідними параметрами:
SELECT *
FROM crosstab(
'SELECT section, status, ct
FROM tbl
ORDER BY 1,2' -- could also just be "ORDER BY 1" here
, $$VALUES ('Active'::text), ('Inactive')$$
) AS ct ("Section" text, "Active" int, "Inactive" int);
Повернення:
Розділ | Активний | Неактивний
--------- + -------- + ----------
А | 1 | 2
Б | 4 | 5
C | | 7 - !!
Зверніть увагу на правильний результат для C.
Другий параметр може бути будь-яким запитом , який повертає один ряд на відповідність атрибута порядку визначення стовпця в кінці. Часто ви хочете запитувати різні атрибути з нижньої таблиці, як це:
'SELECT DISTINCT attribute FROM tbl ORDER BY 1'
Це в посібнику.
Оскільки у будь-якому випадку вам потрібно прописати всі стовпці зі списку визначення стовпців (за винятком попередньо визначених варіантів), як правило, більш ефективно надати короткий список у виразі, як показано:crosstabN()VALUES
$$VALUES ('Active'::text), ('Inactive')$$)
Або (не в посібнику):
$$SELECT unnest('{Active,Inactive}'::text[])$$ -- short syntax for long lists
Я використовував котирування в доларах, щоб полегшити котирування.
Ви можете навіть виводити стовпці з різними типами даних за умови crosstab(text, text), якщо текстове подання стовпця значення є коректним введенням для цільового типу. Таким чином , ви можете мати атрибути різних видів і продукції text, date, і numericт.д. для відповідних атрибутів. Приклад коду є в кінці розділу crosstab(text, text)в посібнику .
db <> скрипка тут
Розширені приклади
\crosstabview в psql
Postgres 9.6 додав цю метакоманду до свого інтерактивного інтерактивного терміналу psql . Ви можете запустити запит, який ви будете використовувати як перший crosstab()параметр, і подати його \crosstabview(негайно або на наступному кроці). Подібно до:
db=> SELECT section, status, ct FROM tbl \crosstabview
Аналогічний результат, як зазначено вище, але це особливість представлення виключно на стороні клієнта . Рядки введення обробляються дещо по-різному, тому ORDER BYне потрібно. Деталі \crosstabviewв посібнику. Є ще приклади коду внизу цієї сторінки.
Відповідна відповідь на dba.SE від Даніеля Верете (автора функції psql):
Раніше прийнятий відповідь застарів.
Варіант функції crosstab(text, integer)застарів. Другий integerпараметр ігнорується. Я цитую поточний посібник :
crosstab(text sql, int N) ...
Застаріла версія crosstab(text). Параметр Nтепер ігнорується, оскільки кількість стовпців значень завжди визначається запитом виклику
Зайве кастинг та перейменування.
Він не вдається, якщо рядок не має всіх атрибутів. Дивіться безпечний варіант з двома вхідними параметрами вище, щоб правильно обробляти відсутні атрибути.
ORDER BYпотрібна в однопараметричній формі crosstab(). Посібник:
На практиці запит SQL повинен завжди вказувати, ORDER BY 1,2щоб забезпечити правильність упорядкування вхідних рядків