Транспонировать представление
Получаю такое представление
| Категория | Период | Количество |
|---|---|---|
| 1 | март 2023 | 100 |
| 1 | апрель 2023 | 200 |
| 2 | март 2023 | 130 |
| 2 | апрель 2023 | 99 |
количество и прочее получаю агрегирующими функциями с группировками, условно:
SELECT Категория, Период, COUNT(что надо посчитать) AS Количество
FROM Таблица
GROUP BY Категория, Период
на самом деле я хочу получить данные в таком виде
| Период | 1 | 2 |
|---|---|---|
| март 2023 | 100 | 130 |
| апрель 2023 | 200 | 99 |
Как это можно получить запросом? Можно конечно сделать скрипт, чтобы создавал новую таблицу, и через INSERT вставлял значения из представления, но может можно прям сразу запросом получить?
БД PostgreSQL
Ответы (3 шт):
Для того, чтобы получить данные в таком виде, можно воспользоваться функцией crosstab из расширения tablefunc. Пример запроса:
SELECT *
FROM crosstab(
'SELECT Период, Категория, COUNT(что надо посчитать) AS Количество
FROM Таблица
GROUP BY Период, Категория
ORDER BY Период, Категория',
'SELECT DISTINCT Категория FROM Таблица ORDER BY Категория'
) AS ct("Период" TEXT, "1" INT, "2" INT);
В этом запросе сначала группируем данные по категориям и периодам, затем используем функцию crosstab, чтобы перевернуть таблицу. Первый аргумент функции - это исходный запрос, второй - запрос, который возвращает список всех категорий. Результат будет иметь тот же формат, что вы кинули.
SELECT
Период,
COUNT(CASE WHEN Категория = 1 THEN что надо посчитать END) AS "1",
COUNT(CASE WHEN Категория = 2 THEN что надо посчитать END) AS "2"
FROM Таблица
GROUP BY Период
На примере столбца "1". Если условие Категория = 1 не выполнено, то результат выражения CASE … END будет NULL, и COUNT эту строку проигнорирует.
Спасибо. Нашел еще такой вариант
SELECT
Период,
count(то что надо посчитать) FILTER(WHERE Категория = 1) AS Category_1,
count(то что надо посчитать) FILTER(WHERE Категория = 2) AS Category_2
FROM Таблица
GROUP BY Период;
Выдало то что надо