PostgreSQL返回和sql元组描述不兼容

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PostgreSQL返回和sql元组描述不兼容相关的知识,希望对你有一定的参考价值。

这个查询出了什么问题?我一直在用数据类型抨击我,但没有看到任何问题。

谢谢。

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个选项:

  1. 将外部类型调整为可变数字类型,例如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
);
  1. 或者,确保交叉表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)
另一答案

谢谢你们的帮助! 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
        )

以上是关于PostgreSQL返回和sql元组描述不兼容的主要内容,如果未能解决你的问题,请参考以下文章

昨天 - 在 Redshift 和 PostgreSQL 中 - 日期添加兼容性

SQL中关于返回查询记录条数的语句

postgresql友好地返回不是'PANDAS'的多行表[重复]

没有从 postgresql 函数返回任何东西?

PostgreSQL存储过程-基于SQL的存储过程

PostgreSQL存储过程-基于SQL的存储过程