PostgreSQL return 和 sql 元组描述不兼容
PostgreSQL return and sql tuple descriptions are incompatible
这个查询有什么问题?我一直在用数据类型抨击我的头脑,但没有发现任何问题。
谢谢。
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
)
虽然您没有提到您遇到的是哪个错误,但这是使其工作的方法:
初始化模块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 returns 明确是所需的类型,例如:
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)
谢谢大家的帮助! 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
)
这个查询有什么问题?我一直在用数据类型抨击我的头脑,但没有发现任何问题。
谢谢。
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
)
虽然您没有提到您遇到的是哪个错误,但这是使其工作的方法:
初始化模块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 returns 明确是所需的类型,例如:
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)
谢谢大家的帮助! 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
)