Errors
Redash

Redash: AWS Redshift: columns into rows (wide to long)

Ты написал запрос в Redash, который считает сумму по трём колонкам за месяц. Всё правильно, логично, но вот беда — результат выглядит как одна строка с тремя чи

Ты написал запрос в Redash, который считает сумму по трём колонкам за месяц. Всё правильно, логично, но вот беда — результат выглядит как одна строка с тремя числами.

А для красивого дашборда в Redash тебе нужно, чтобы каждая метрика была отдельной строкой. Потому что визуализации — таблицы, графики — часто заточены под long-формат: «название показателя» и «его значение».

Твои данные сейчас wide (широкие), а нужны long (длинные). В SQL-мир это классическая задача pivot/unpivot.

Простое решение: UNION ALL

Самый прямой путь — разбить один запрос на три и склеить их. Выглядит грубовато, но работает без магии.

SELECT 'col_A' as column, sum(col_A) as sum
FROM table_X
WHERE timestamp > '2018-01-01' AND timestamp < '2018-02-01'
UNION ALL
SELECT 'col_B', sum(col_B)
FROM table_X
WHERE timestamp > '2018-01-01' AND timestamp < '2018-02-01'
UNION ALL
SELECT 'col_C', sum(col_C)
FROM table_X
WHERE timestamp > '2018-01-01' AND timestamp < '2018-02-01';

Так мы получаем ровно ту структуру, которая нужна: column и sum. Важно не забыть жёстко прописать названия колонок в первой части, иначе получим нечитаемый результат.

Да, запрос выполнит три сканирования таблицы. Но Redshift — колоночная СУБД. Это значит, что при каждом прогоне будет читаться только нужная колонка (col_A, col_B или col_C), а не вся таблица целиком. Так что потери не так страшны, как кажутся.

Более элегантный способ: UNPIVOT

В Redshift есть и более компактный оператор — UNPIVOT. Он создан как раз для таких преобразований.

SELECT column, sum(value)
FROM table_X
UNPIVOT (value FOR column IN (col_A, col_B, col_C))
WHERE timestamp > '2018-01-01' AND timestamp < '2018-02-01'
GROUP BY column;

Что здесь происходит? UNPIVOT берёт несколько колонок (col_A, col_B, col_C) и превращает их в пары: название колонки (column) и её значение (value). Дальше с этим результатом можно работать как с обычной таблицей — фильтровать, агрегировать.

Этот запрос читается легче и, вероятно, выполнится за одно сканирование данных. Но нужно помнить про совместимость — UNPIVOT поддерживается в современных версиях Redshift.

Итог

Выбор между UNION ALL и UNPIVOT — это вопрос стиля и требований к производительности. Для трёх колонок разница будет минимальна.

Главное — теперь твой результат готов для Redash. Загружаешь его, выбираешь визуализацию (например, «Значение и текст»), назначаешь поля «column» и «sum» — и дашборд оживает.

Не нужно менять данные на стороне приложения или городить костыли в Redash. Всё решается на уровне SQL-запроса. Как и должно быть.