\crosstabview в psql

PostgreSQLПериодически читаю страницу документации, посвященную утилите psql. Каждый раз там что-то новое для себя нахожу. Некоторое время назад прочитал там про метакоманду этой утилиты \crosstabview — создание перекрёстной (сводной) таблицы, типа электронной таблицы.

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

Пару раз читал уже про эту команду \crosstabview, но всё откладывал время её разбора. И вот оно пришло!

Примеры работы crosstabview, которые я находил в интернете были какие-то абстрактные. Поэтому я решил взять более понятный пример (но тоже простой) и на его основе показать как работает crosstabview. А показывать я буду на примере моего читательского плана, отчет возьму за 2019 год (ведь мне в следующем году формировать читательский отчет за 2022 год, вот — может немного автоматизирую этот процесс).

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

CREATE TABLE t_crosstab (name text, month text, country text, pol char(1), day text, genre text);

И добавляю туда все прочитанные книги за 2019 год, просто выделите всё из раскрывающегося блока внизу и выполните:

Инсерты в таблицу t_crosstab

INSERT INTO t_crosstab VALUES (‘Искусство объяснять’,’01. Январь’,’США’,’М’,’пятница’,’Нехудожественная’);
INSERT INTO t_crosstab VALUES (‘Пандемониум’,’01. Январь’,’США’,’Ж’,’четверг’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Пятнадцатилетний капитан’,’01. Январь’,’Франция’,’М’,’четверг’,’Приключения’);
INSERT INTO t_crosstab VALUES (‘Реквием’,’01. Январь’,’США’,’Ж’,’понедельник’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Бесы’,’01. Январь’,’Россия’,’М’,’понедельник’,’Психологический реализм’);
INSERT INTO t_crosstab VALUES (‘Северное сияние’,’02. Февраль’,’Великобритания’,’М’,’воскресенье’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Чудесный нож’,’02. Февраль’,’Великобритания’,’М’,’пятница’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Янтарный телескоп’,’02. Февраль’,’Великобритания’,’М’,’четверг’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Меч без имени’,’02. Февраль’,’Россия’,’М’,’воскресенье’,’Фэнтези’);
INSERT INTO t_crosstab VALUES (‘Свирепый ландграф’,’02. Февраль’,’Россия’,’М’,’четверг’,’Фэнтези’);
INSERT INTO t_crosstab VALUES (‘Век святого Скиминока’,’02. Февраль’,’Россия’,’М’,’вторник’,’Фэнтези’);
INSERT INTO t_crosstab VALUES (‘Палата номер шесть’,’02. Февраль’,’Россия’,’М’,’четверг’,’Психологический реализм’);
INSERT INTO t_crosstab VALUES (‘Чувство и чувствительность’,’03. Март’,’Великобритания’,’Ж’,’среда’,’Любовный роман’);
INSERT INTO t_crosstab VALUES (‘Гордость и предубеждение’,’03. Март’,’Великобритания’,’Ж’,’воскресенье’,’Любовный роман’);
INSERT INTO t_crosstab VALUES (‘Мэнсфилд-парк’,’03. Март’,’Великобритания’,’Ж’,’пятница’,’Любовный роман’);
INSERT INTO t_crosstab VALUES (‘Эмма’,’03. Март’,’Великобритания’,’Ж’,’среда’,’Любовный роман’);
INSERT INTO t_crosstab VALUES (‘Доводы рассудка’,’03. Март’,’Великобритания’,’Ж’,’понедельник’,’Любовный роман’);
INSERT INTO t_crosstab VALUES (‘Нортенгерское аббатство’,’03. Март’,’Великобритания’,’Ж’,’пятница’,’Любовный роман’);
INSERT INTO t_crosstab VALUES (‘Евгений Онегин’,’03. Март’,’Россия’,’М’,’суббота’,’Поэзия’);
INSERT INTO t_crosstab VALUES (‘Тарас Бульба’,’04. Апрель’,’Россия’,’М’,’понедельник’,’Приключения’);
INSERT INTO t_crosstab VALUES (‘Братья Карамазовы’,’04. Апрель’,’Россия’,’М’,’четверг’,’Психологический реализм’);
INSERT INTO t_crosstab VALUES (‘Ревизор’,’04. Апрель’,’Россия’,’М’,’четверг’,’Психологический реализм’);
INSERT INTO t_crosstab VALUES (‘Доктор Живаго’,’04. Апрель’,’Россия’,’М’,’воскресенье’,’Психологический реализм’);
INSERT INTO t_crosstab VALUES (‘RUR’,’04. Апрель’,’Чехия’,’М’,’вторник’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Левша’,’04. Апрель’,’Россия’,’М’,’четверг’,’Фэнтези’);
INSERT INTO t_crosstab VALUES (‘Тошнота’,’04. Апрель’,’Франция’,’М’,’суббота’,’Психологический реализм’);
INSERT INTO t_crosstab VALUES (‘Белая гвардия’,’04. Апрель’,’Россия’,’М’,’вторник’,’Психологический реализм’);
INSERT INTO t_crosstab VALUES (‘Стрелок’,’05. Май’,’США’,’М’,’четверг’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Извлечение троих’,’05. Май’,’США’,’М’,’суббота’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Бесплодные земли’,’05. Май’,’США’,’М’,’четверг’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Кодун и кристалл’,’05. Май’,’США’,’М’,’пятница’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Ветер сквозь замочную скважину’,’05. Май’,’США’,’М’,’воскресенье’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Волки Кальи’,’05. Май’,’США’,’М’,’среда’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Песнь Сюзанны’,’06. Июнь’,’США’,’М’,’вторник’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Тёмная башня’,’06. Июнь’,’США’,’М’,’пятница’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Планета обезьян’,’06. Июнь’,’Франция’,’М’,’понедельник’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Лисистрата’,’06. Июнь’,’Греция’,’М’,’понедельник’,’Фэнтези’);
INSERT INTO t_crosstab VALUES (‘Чемодан миссис Синклер’,’06. Июнь’,’Великобритания’,’Ж’,’четверг’,’Любовный роман’);
INSERT INTO t_crosstab VALUES (‘Маленькая хозяйка большого дома’,’06. Июнь’,’США’,’М’,’вторник’,’Психологический реализм’);
INSERT INTO t_crosstab VALUES (‘Обезьяна и сущность’,’06. Июнь’,’США’,’М’,’среда’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Дочь снегов’,’07. Июль’,’США’,’М’,’понедельник’,’Психологический реализм’);
INSERT INTO t_crosstab VALUES (‘Голова профессора Доуэля’,’07. Июль’,’Россия’,’М’,’среда’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Грозовой перевал’,’07. Июль’,’Великобритания’,’Ж’,’суббота’,’Психологический реализм’);
INSERT INTO t_crosstab VALUES (‘Улитка на склоне’,’07. Июль’,’Россия’,’М’,’четверг’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Педагогика для всех’,’07. Июль’,’Россия’,’М’,’суббота’,’Нехудожественная’);
INSERT INTO t_crosstab VALUES (‘Искусство обучать’,’07. Июль’,’США’,’Ж’,’среда’,’Нехудожественная’);
INSERT INTO t_crosstab VALUES (‘Солярис’,’08. Август’,’Польша’,’М’,’суббота’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Слепящая тьма’,’08. Август’,’Великобритания’,’М’,’вторник’,’Исторический роман’);
INSERT INTO t_crosstab VALUES (‘Трудно быть богом’,’08. Август’,’Россия’,’М’,’четверг’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Загадочная история Бенджамина Баттона’,’08. Август’,’США’,’М’,’пятница’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Коллекционер’,’08. Август’,’Великобритания’,’М’,’среда’,’Психологический реализм’);
INSERT INTO t_crosstab VALUES (‘Пять недель на воздушном шаре’,’08. Август’,’Франция’,’М’,’понедельник’,’Приключения’);
INSERT INTO t_crosstab VALUES (‘Джейн Эйр’,’08. Август’,’Великобритания’,’Ж’,’пятница’,’Психологический реализм’);
INSERT INTO t_crosstab VALUES (‘Цвет волшебства’,’08. Август’,’Великобритания’,’М’,’четверг’,’Фэнтези’);
INSERT INTO t_crosstab VALUES (‘Безумная звезда’,’09. Сентябрь’,’Великобритания’,’М’,’вторник’,’Фэнтези’);
INSERT INTO t_crosstab VALUES (‘Посох и шляпа’,’09. Сентябрь’,’Великобритания’,’М’,’суббота’,’Фэнтези’);
INSERT INTO t_crosstab VALUES (‘Село Степанчиково и его обитатели’,’09. Сентябрь’,’Россия’,’М’,’вторник’,’Психологический реализм’);
INSERT INTO t_crosstab VALUES (‘Путешествие на «Ослепительном»‘,’09. Сентябрь’,’США’,’М’,’среда’,’Приключения’);
INSERT INTO t_crosstab VALUES (‘Морской волк’,’09. Сентябрь’,’США’,’М’,’среда’,’Приключения’);
INSERT INTO t_crosstab VALUES (‘Эрик, а также Ночная стража, ведьмы и Коэн-Варвар’,’09. Сентябрь’,’Великобритания’,’М’,’пятница’,’Фэнтези’);
INSERT INTO t_crosstab VALUES (‘Путешествие и приключения капитана Гаттераса’,’09. Сентябрь’,’Франция’,’М’,’понедельник’,’Приключения’);
INSERT INTO t_crosstab VALUES (‘Железная пята’,’10. Октябрь’,’США’,’М’,’суббота’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Интересные времена’,’10. Октябрь’,’Великобритания’,’М’,’четверг’,’Фэнтези’);
INSERT INTO t_crosstab VALUES (‘Алые паруса’,’10. Октябрь’,’Россия’,’М’,’пятница’,’Психологический реализм’);
INSERT INTO t_crosstab VALUES (‘Бегущая по волнам’,’10. Октябрь’,’Россия’,’М’,’понедельник’,’Психологический реализм’);
INSERT INTO t_crosstab VALUES (‘Море-Океан’,’10. Октябрь’,’Италия’,’М’,’среда’,’Психологический реализм’);
INSERT INTO t_crosstab VALUES (‘Алиса в стране чудес’,’10. Октябрь’,’Великобритания’,’М’,’пятница’,’Фэнтези’);
INSERT INTO t_crosstab VALUES (‘Алиса в Зазеркалье’,’10. Октябрь’,’Великобритания’,’М’,’понедельник’,’Фэнтези’);
INSERT INTO t_crosstab VALUES (‘Обитаемый остров’,’10. Октябрь’,’Россия’,’М’,’вторник’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Хижина дяди Тома’,’11. Ноябрь’,’США’,’Ж’,’суббота’,’Психологический реализм’);
INSERT INTO t_crosstab VALUES (‘Жук в муравейнике’,’11. Ноябрь’,’Россия’,’М’,’среда’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Волны гасят ветер’,’11. Ноябрь’,’Россия’,’М’,’пятница’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Кэрри’,’11. Ноябрь’,’США’,’М’,’среда’,’Ужасы’);
INSERT INTO t_crosstab VALUES (‘Последний континент’,’11. Ноябрь’,’Великобритания’,’М’,’среда’,’Фэнтези’);
INSERT INTO t_crosstab VALUES (‘Рассказ служанки’,’11. Ноябрь’,’Канада’,’Ж’,’понедельник’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Изобретение Мореля’,’11. Ноябрь’,’Аргентина’,’М’,’среда’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘И пришло разрушение…’,’11. Ноябрь’,’Нигерия’,’М’,’четверг’,’Исторический роман’);
INSERT INTO t_crosstab VALUES (‘Приют грез’,’12. Декабрь’,’Германия’,’М’,’воскресенье’,’Психологический реализм’);
INSERT INTO t_crosstab VALUES (‘Колыбель для кошки’,’12. Декабрь’,’США’,’М’,’среда’,’Фантастика’);
INSERT INTO t_crosstab VALUES (‘Изобретено в России’,’12. Декабрь’,’Россия’,’М’,’вторник’,’Нехудожественная’);
INSERT INTO t_crosstab VALUES (‘Изобретено в СССР’,’12. Декабрь’,’Россия’,’М’,’понедельник’,’Нехудожественная’);
INSERT INTO t_crosstab VALUES (‘Последний герой. Сказание о плоском мире’,’12. Декабрь’,’Великобритания’,’М’,’среда’,’Фэнтези’);
INSERT INTO t_crosstab VALUES (‘Старик и море’,’12. Декабрь’,’США’,’М’,’четверг’,’Психологический реализм’);
INSERT INTO t_crosstab VALUES (‘Педро Парамо’,’12. Декабрь’,’Мексика’,’М’,’суббота’,’Мистика’);
INSERT INTO t_crosstab VALUES (‘Незримые академики’,’12. Декабрь’,’Великобритания’,’М’,’четверг’,’Фэнтези’);

[свернуть]

Как это и должно быть, в таблице у нас примерно вот что:

SELECT * FROM t_crosstab limit 10;
+--------------------------+---------+----------------+-----+-------------+-------------------------+
|           name           |  month  |    country     | pol |     day     |          genre          |
+--------------------------+---------+----------------+-----+-------------+-------------------------+
| Искусство объяснять      | 01. Январь  | США            | М   | пятница     | Нехудожественная        |
| Пандемониум              | 01. Январь  | США            | Ж   | четверг     | Фантастика              |
| Пятнадцатилетний капитан | 01. Январь  | Франция        | М   | четверг     | Приключения             |
| Реквием                  | 01. Январь  | США            | Ж   | понедельник | Фантастика              |
| Бесы                     | 01. Январь  | Россия         | М   | понедельник | Психологический реализм |
| Северное сияние          | 02. Февраль | Великобритания | М   | воскресенье | Фантастика              |
| Чудесный нож             | 02. Февраль | Великобритания | М   | пятница     | Фантастика              |
| Янтарный телескоп        | 02. Февраль | Великобритания | М   | четверг     | Фантастика              |
| Меч без имени            | 02. Февраль | Россия         | М   | воскресенье | Фэнтези                 |
| Свирепый ландграф        | 02. Февраль | Россия         | М   | четверг     | Фэнтези                 |
+--------------------------+---------+----------------+-----+-------------+-------------------------+
(10 rows)

Глянем простой запрос — сколько я прочитал штук книг по месяцам:

SELECT month, count(*) FROM t_crosstab
GROUP BY month
ORDER BY month;
+--------------+-------+
|    month     | count |
+--------------+-------+
| 01. Январь   |     5 |
| 02. Февраль  |     7 |
| 03. Март     |     7 |
| 04. Апрель   |     8 |
| 05. Май      |     6 |
| 06. Июнь     |     7 |
| 07. Июль     |     6 |
| 08. Август   |     8 |
| 09. Сентябрь |     7 |
| 10. Октябрь  |     8 |
| 11. Ноябрь   |     8 |
| 12. Декабрь  |     8 |
+--------------+-------+
(12 rows)

Но хотелось бы получить что-нибудь посложнее — одним запросом вывести сводную таблицу, где были бы месяцы (по вертикали), страны книг (по вертикали), а на их пересечении — количество книг из определенной страны, которые я прочитал в определенном месяце.

Но сам запрос я не буду писать, а воспользуюсь командой crosstabview:

SELECT month, country, COUNT(country) cnt FROM t_crosstab 
GROUP BY month, country 
\crosstabview month country cnt
+--------------+-----+--------+----------------+-----------+---------+---------+--------+--------+---------+--------+--------+----------+-------+
|    month     | США | Россия | Великобритания | Аргентина | Мексика | Франция | Польша | Италия | Нигерия | Греция | Канада | Германия | Чехия |
+--------------+-----+--------+----------------+-----------+---------+---------+--------+--------+---------+--------+--------+----------+-------+
| 06. Июнь     |   4 |        |              1 |           |         |       1 |        |        |         |      1 |        |          |       |
| 05. Май      |   6 |        |                |           |         |         |        |        |         |        |        |          |       |
| 01. Январь   |   3 |      1 |                |           |         |       1 |        |        |         |        |        |          |       |
| 11. Ноябрь   |   2 |      2 |              1 |         1 |         |         |        |        |       1 |        |      1 |          |       |
| 09. Сентябрь |   2 |      1 |              3 |           |         |       1 |        |        |         |        |        |          |       |
| 12. Декабрь  |   2 |      2 |              2 |           |       1 |         |        |        |         |        |        |        1 |       |
| 02. Февраль  |     |      4 |              3 |           |         |         |        |        |         |        |        |          |       |
| 04. Апрель   |     |      6 |                |           |         |       1 |        |        |         |        |        |          |     1 |
| 03. Март     |     |      1 |              6 |           |         |         |        |        |         |        |        |          |       |
| 07. Июль     |   2 |      3 |              1 |           |         |         |        |        |         |        |        |          |       |
| 08. Август   |   1 |      1 |              4 |           |         |       1 |      1 |        |         |        |        |          |       |
| 10. Октябрь  |   1 |      3 |              3 |           |         |         |        |      1 |         |        |        |          |       |
+--------------+-----+--------+----------------+-----------+---------+---------+--------+--------+---------+--------+--------+----------+-------+
(12 rows)

Результат можно отсортировать. Сделаем это для месяцев:

SELECT month, country, COUNT(country) cnt FROM t_crosstab 
GROUP BY month, country 
ORDER BY month         
\crosstabview month country cnt
+--------------+---------+--------+-----+----------------+-------+--------+--------+--------+-----------+--------+---------+---------+----------+
|    month     | Франция | Россия | США | Великобритания | Чехия | Греция | Польша | Италия | Аргентина | Канада | Нигерия | Мексика | Германия |
+--------------+---------+--------+-----+----------------+-------+--------+--------+--------+-----------+--------+---------+---------+----------+
| 01. Январь   |       1 |      1 |   3 |                |       |        |        |        |           |        |         |         |          |
| 02. Февраль  |         |      4 |     |              3 |       |        |        |        |           |        |         |         |          |
| 03. Март     |         |      1 |     |              6 |       |        |        |        |           |        |         |         |          |
| 04. Апрель   |       1 |      6 |     |                |     1 |        |        |        |           |        |         |         |          |
| 05. Май      |         |        |   6 |                |       |        |        |        |           |        |         |         |          |
| 06. Июнь     |       1 |        |   4 |              1 |       |      1 |        |        |           |        |         |         |          |
| 07. Июль     |         |      3 |   2 |              1 |       |        |        |        |           |        |         |         |          |
| 08. Август   |       1 |      1 |   1 |              4 |       |        |      1 |        |           |        |         |         |          |
| 09. Сентябрь |       1 |      1 |   2 |              3 |       |        |        |        |           |        |         |         |          |
| 10. Октябрь  |         |      3 |   1 |              3 |       |        |        |      1 |           |        |         |         |          |
| 11. Ноябрь   |         |      2 |   2 |              1 |       |        |        |        |         1 |      1 |       1 |         |          |
| 12. Декабрь  |         |      2 |   2 |              2 |       |        |        |        |           |        |         |       1 |        1 |
+--------------+---------+--------+-----+----------------+-------+--------+--------+--------+-----------+--------+---------+---------+----------+
(12 rows)

Вот теперь чуть лучше. Взглянув на эту таблицу — сразу можно сказать что книг отечественных авторов и авторов из США я читал в течении года довольно много. Ну и из Великобритании тоже. Для формирования этого результата не понадобилось какие-то там агрегатные функции, CTE использовать.

В перечне столбцов после указания crosstabview можно использовать позиционное указание столбцов, например, так:

SELECT country, COUNT(country) cnt, month FROM t_crosstab 
GROUP BY 3, 1 
ORDER BY 3, 1
\crosstabview 1 3 2
+----------------+------------+-------------+----------+------------+---------+----------+----------+------------+--------------+-------------+------------+-------------+
|    country     | 01. Январь | 02. Февраль | 03. Март | 04. Апрель | 05. Май | 06. Июнь | 07. Июль | 08. Август | 09. Сентябрь | 10. Октябрь | 11. Ноябрь | 12. Декабрь |
+----------------+------------+-------------+----------+------------+---------+----------+----------+------------+--------------+-------------+------------+-------------+
| Россия         |          1 |           4 |        1 |          6 |         |          |        3 |          1 |            1 |           3 |          2 |           2 |
| США            |          3 |             |          |            |       6 |        4 |        2 |          1 |            2 |           1 |          2 |           2 |
| Франция        |          1 |             |          |          1 |         |        1 |          |          1 |            1 |             |            |             |
| Великобритания |            |           3 |        6 |            |         |        1 |        1 |          4 |            3 |           3 |          1 |           2 |
| Чехия          |            |             |          |          1 |         |          |          |            |              |             |            |             |
| Греция         |            |             |          |            |         |        1 |          |            |              |             |            |             |
| Польша         |            |             |          |            |         |          |          |          1 |              |             |            |             |
| Италия         |            |             |          |            |         |          |          |            |              |           1 |            |             |
| Аргентина      |            |             |          |            |         |          |          |            |              |             |          1 |             |
| Канада         |            |             |          |            |         |          |          |            |              |             |          1 |             |
| Нигерия        |            |             |          |            |         |          |          |            |              |             |          1 |             |
| Германия       |            |             |          |            |         |          |          |            |              |             |            |           1 |
| Мексика        |            |             |          |            |         |          |          |            |              |             |            |           1 |
+----------------+------------+-------------+----------+------------+---------+----------+----------+------------+--------------+-------------+------------+-------------+
(13 rows)

А есть еще и вот такой способ использовать — не будем группировку использовать, а разобьем прочитанные книги по жанрам и полу, и всё это выведем в одной таблице. Но сделаем следующим образом — сначала сформируем запрос (выполним его отдельно), проверим что он работает, а потом уже запустим crosstabview:

SELECT name, pol, genre FROM crosstab LIMIT 20;
+----------------------------+-----+-------------------------+
|            name            | pol |          genre          |
+----------------------------+-----+-------------------------+
| Искусство объяснять        | М   | Нехудожественная        |
| Пандемониум                | Ж   | Фантастика              |
| Пятнадцатилетний капитан   | М   | Приключения             |
| Реквием                    | Ж   | Фантастика              |
| Бесы                       | М   | Психологический реализм |
| Северное сияние            | М   | Фантастика              |
| Чудесный нож               | М   | Фантастика              |
| Янтарный телескоп          | М   | Фантастика              |
| Меч без имени              | М   | Фэнтези                 |
| Свирепый ландграф          | М   | Фэнтези                 |
| Век святого Скиминока      | М   | Фэнтези                 |
| Палата номер шесть         | М   | Психологический реализм |
| Чувство и чувствительность | Ж   | Любовный роман          |
| Гордость и предубеждение   | Ж   | Любовный роман          |
| Мэнсфилд-парк              | Ж   | Любовный роман          |
| Эмма                       | Ж   | Любовный роман          |
| Доводы рассудка            | Ж   | Любовный роман          |
| Нортенгерское аббатство    | Ж   | Любовный роман          |
| Евгений Онегин             | М   | Поэзия                  |
| Тарас Бульба               | М   | Приключения             |
+----------------------------+-----+-------------------------+
(20 rows)

Я ограниченное число строк использую, чтобы не загромождать страницу. Убиделись что всё работает. А теперь выполним crosstabview:

\crosstabview 1 2 3
+----------------------------+-------------------------+----------------+
|            name            |            М            |       Ж        |
+----------------------------+-------------------------+----------------+
| Искусство объяснять        | Нехудожественная        |                |
| Пандемониум                |                         | Фантастика     |
| Пятнадцатилетний капитан   | Приключения             |                |
| Реквием                    |                         | Фантастика     |
| Бесы                       | Психологический реализм |                |
| Северное сияние            | Фантастика              |                |
| Чудесный нож               | Фантастика              |                |
| Янтарный телескоп          | Фантастика              |                |
| Меч без имени              | Фэнтези                 |                |
| Свирепый ландграф          | Фэнтези                 |                |
| Век святого Скиминока      | Фэнтези                 |                |
| Палата номер шесть         | Психологический реализм |                |
| Чувство и чувствительность |                         | Любовный роман |
| Гордость и предубеждение   |                         | Любовный роман |
| Мэнсфилд-парк              |                         | Любовный роман |
| Эмма                       |                         | Любовный роман |
| Доводы рассудка            |                         | Любовный роман |
| Нортенгерское аббатство    |                         | Любовный роман |
| Евгений Онегин             | Поэзия                  |                |
| Тарас Бульба               | Приключения             |                |
+----------------------------+-------------------------+----------------+
(20 rows)

И это у нас отдельный запрос, так тоже можно. Глядя на соотношение пол-жанр можно некоторые выводы сделать.

А еще — можно поменять параметры crosstabview повторно не указывая запрос, crosstabview отработает для предыдущего запроса:

\crosstabview 1 3 2
+----------------------------+------------------+------------+-------------+-------------------------+---------+----------------+--------+
|            name            | Нехудожественная | Фантастика | Приключения | Психологический реализм | Фэнтези | Любовный роман | Поэзия |
+----------------------------+------------------+------------+-------------+-------------------------+---------+----------------+--------+
| Искусство объяснять        | М                |            |             |                         |         |                |        |
| Пандемониум                |                  | Ж          |             |                         |         |                |        |
| Пятнадцатилетний капитан   |                  |            | М           |                         |         |                |        |
| Реквием                    |                  | Ж          |             |                         |         |                |        |
| Бесы                       |                  |            |             | М                       |         |                |        |
| Северное сияние            |                  | М          |             |                         |         |                |        |
| Чудесный нож               |                  | М          |             |                         |         |                |        |
| Янтарный телескоп          |                  | М          |             |                         |         |                |        |
| Меч без имени              |                  |            |             |                         | М       |                |        |
| Свирепый ландграф          |                  |            |             |                         | М       |                |        |
| Век святого Скиминока      |                  |            |             |                         | М       |                |        |
| Палата номер шесть         |                  |            |             | М                       |         |                |        |
| Чувство и чувствительность |                  |            |             |                         |         | Ж              |        |
| Гордость и предубеждение   |                  |            |             |                         |         | Ж              |        |
| Мэнсфилд-парк              |                  |            |             |                         |         | Ж              |        |
| Эмма                       |                  |            |             |                         |         | Ж              |        |
| Доводы рассудка            |                  |            |             |                         |         | Ж              |        |
| Нортенгерское аббатство    |                  |            |             |                         |         | Ж              |        |
| Евгений Онегин             |                  |            |             |                         |         |                | М      |
| Тарас Бульба               |                  |            | М           |                         |         |                |        |
+----------------------------+------------------+------------+-------------+-------------------------+---------+----------------+--------+
(20 rows)

Можно подобрать и более интересные примеры, например, на демобазе. Но, возможно, займусь этим когда-нибудь попозже.

Напоследок, с помощью специальной переменной psql ECHO_HIDDEN посмотрим тот запрос, который формирует psql:

\set ECHO_HIDDEN on

И повторим запрос:

SELECT country, COUNT(country) cnt, month FROM t_crosstab
GROUP BY month, country
ORDER BY 1
LIMIT 20
\crosstabview 1 3 2
+----------------+------------+-------------+--------------+------------+----------+-------------+----------+----------+-------------+
|    country     | 11. Ноябрь | 02. Февраль | 09. Сентябрь | 08. Август | 03. Март | 12. Декабрь | 07. Июль | 06. Июнь | 10. Октябрь |
+----------------+------------+-------------+--------------+------------+----------+-------------+----------+----------+-------------+
| Аргентина      |          1 |             |              |            |          |             |          |          |             |
| Великобритания |          1 |           3 |            3 |          4 |        6 |           2 |        1 |        1 |           3 |
| Германия       |            |             |              |            |          |           1 |          |          |             |
| Греция         |            |             |              |            |          |             |          |        1 |             |
| Италия         |            |             |              |            |          |             |          |          |           1 |
| Канада         |          1 |             |              |            |          |             |          |          |             |
| Мексика        |            |             |              |            |          |           1 |          |          |             |
| Нигерия        |          1 |             |              |            |          |             |          |          |             |
| Польша         |            |             |              |          1 |          |             |          |          |             |
| Россия         |          2 |             |            1 |            |          |           2 |          |          |             |
+----------------+------------+-------------+--------------+------------+----------+-------------+----------+----------+-------------+
(10 rows)

Ничего дополнительно не появилось. Я внимательнее почитал про эту переменную — если метакоманда psql обращается к БД, тогда будет выведен текст запроса. А у нас метакоманда crosstabview не обращается к базе. Так что всё логично.


Be the first to comment

Leave a Reply

Ваш Mail не будет опубликован.


*