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-запроса. Как и должно быть.