#postgresql #crosstab
#postgresql #перекрестная таблица
Вопрос:
Что не так с этим запросом? Я ломал голову над типом данных, но не увидел никакой проблемы.
Спасибо.
select * from crosstab(
$$
select * from
(values
(1546300800, 187923, 1.5),
(1546300800, 187924, 200),
(1546300800, 187926, 120),
(1546300800, 187927, 100),
(1546387200, 187923, 1.5),
(1546387200, 187924, 250),
(1546387200, 187926, 120),
(1546387200, 187927, 125),
(1546473600, 187923, 1.5),
(1546473600, 187924, 275),
(1546473600, 187926, 120),
(1546473600, 187927, 137.5),
(1546560000, 187923, 1.75)
) as t (datetime, trace, value)
$$
)
as final_result (
unixdatetime int,
trace1 double precision,
trace2 double precision,
trace3 double precision,
trace4 double precision
)
Комментарии:
1. У вас действительно настроен
tablefunc
модуль?create extension tablefunc;
Ответ №1:
Хотя вы не упомянули, какую ошибку вы получаете, вот как заставить ее работать:
Инициализируйте модуль tablefunc
:
CREATE EXTENSION tablefunc;
Затем вам нужно быть осторожным с типами данных. PostgreSQL может быть довольно требовательным и во многих случаях не преобразует их автоматически, как по волшебству. В этом случае они должны совпадать или, по крайней мере, определения типов столбцов перекрестной таблицы должны быть способны полностью содержать типы, возвращаемые функцией перекрестной таблицы SQL.
Здесь у вас есть 2 варианта:
- Адаптируйте внешний тип к числовому типу переменной, например
decimal
:
select * from crosstab(
$$
select * from (values
(1546300800, 187923, 1.5),
(1546300800, 187924, 200),
(1546300800, 187926, 120),
(1546300800, 187927, 100),
(1546387200, 187923, 1.5),
(1546387200, 187924, 250),
(1546387200, 187926, 120),
(1546387200, 187927, 125),
(1546473600, 187923, 1.5),
(1546473600, 187924, 275),
(1546473600, 187926, 120),
(1546473600, 187927, 137.5),
(1546560000, 187923, 1.75)
) as t (datetime, trace, value)
$$
) as final_result (
unixdatetime int,
trace1 decimal,
trace2 decimal,
trace3 decimal,
trace4 decimal
);
- В качестве альтернативы, убедитесь, что перекрестная таблица SQL возвращает желаемый тип явно, например:
select * from crosstab(
$$
select * from (values
(1546300800, 187923, 1.5::double precision),
(1546300800, 187924, 200::double precision),
(1546300800, 187926, 120::double precision),
(1546300800, 187927, 100::double precision),
(1546387200, 187923, 1.5::double precision),
(1546387200, 187924, 250::double precision),
(1546387200, 187926, 120::double precision),
(1546387200, 187927, 125::double precision),
(1546473600, 187923, 1.5::double precision),
(1546473600, 187924, 275::double precision),
(1546473600, 187926, 120::double precision),
(1546473600, 187927, 137.5::double precision),
(1546560000, 187923, 1.75::double precision)
) as t (datetime, trace, value)
$$
) as final_result (
unixdatetime int,
trace1 double precision,
trace2 double precision,
trace3 double precision,
trace4 double precision
);
Результат в обоих случаях выглядит следующим образом:
unixdatetime | trace1 | trace2 | trace3 | trace4
-------------- -------- -------- -------- --------
1546300800 | 1.5 | 200 | 120 | 100
1546387200 | 1.5 | 250 | 120 | 125
1546473600 | 1.5 | 275 | 120 | 137.5
1546560000 | 1.75 | | |
(4 rows)
Ответ №2:
Спасибо вам, ребята, за помощь! Решение Ancoron сработало отлично.
Что касается второго решения, вместо явного приведения каждого значения в каждой строке к двойной точности, мы можем применить приведение типа к имени столбца, как в приведенном ниже коде:
select * from crosstab(
$$
select datetime, trace, value::double precision from
(values
(1546300800, 187923, 1.5),
(1546300800, 187924, 200),
(1546300800, 187926, 120),
(1546300800, 187927, 100),
(1546387200, 187923, 1.5),
(1546387200, 187924, 250),
(1546387200, 187926, 120),
(1546387200, 187927, 125),
(1546473600, 187923, 1.5),
(1546473600, 187924, 275),
(1546473600, 187926, 120),
(1546473600, 187927, 137.5),
(1546560000, 187923, 1.75)
) as t (datetime, trace, value)
$$
)
as final_result (
unixdatetime int,
trace1 double precision,
trace2 double precision,
trace3 double precision,
trace4 double precision
)