我有以下功能:
CREATE OR REPLACE FUNCTION aggregate_view(ticker text, from_time timestamp)
RETURNS TABLE (data text)
LANGUAGE sql AS
$func$
SELECT
json_build_object(
'candles',
(SELECT json_agg(array [EXTRACT(EPOCH FROM ts_bucket), "open", high, low, "close", volume :: BIGINT]) AS json_array_of_arrays
FROM exchange.candles_d1
WHERE exchange.candles_d1.ticker = $1 AND candles_d1.ts_bucket >= $2 AND candles_d1.ts_bucket < $2 + INTERVAL '1 hour'),
'kvwap',
(SELECT json_agg(array [EXTRACT(EPOCH FROM ts_bucket), m1, m5, m15, m30, h1, h2, h4, d1, low, vwap, high]) AS json_array_of_arrays
FROM exchange.kvwap_d1
WHERE exchange.kvwap_d1.ticker = $1 AND kvwap_d1.ts_bucket >= $2 AND kvwap_d1.ts_bucket < $2 + INTERVAL '1 hour'),
'zones',
(SELECT json_agg(array[EXTRACT(EPOCH FROM ts_confirmation)::BIGINT, EXTRACT(EPOCH FROM ts_end)::BIGINT, confirmations, CAST(is_continuation AS INT)])
AS json_array_of_array
FROM analysis.zones
WHERE analysis.zones.ticker = $1 AND "interval" = 'D1' AND ts_confirmation >= $2 AND ts_confirmation < $2+ INTERVAL '1 hour')
)
$func$;
时间戳存储为(time - EPOCH),但在输出json中,格式因表而异。每个块中的第一个值是时间戳:
{
"candles":[
[
1577836800,
7189.43,
7260.43,
7170.15,
7197.57,
409678761
]
],
"kvwap":[
[
1.5778368e+09,
7213.8125,
7213.5947,
7212.4907,
7210.914,
7209.1133,
7207.789,
7207.2,
7206.961,
7170.15,
7213.8574,
7260.43
]
],
"zones":null
}
注意一个时间戳是如何写成***1577836800***的,而另一个时间戳是如何写成***1.5778368e+09***的,它们是相同的数字。
为什么会这样呢?如何防止数字以科学记数法显示呢?
1条答案
按热度按时间yc0p9oo01#
Postgres数组存储一个数据类型的元素。如果输入类型不同,ARRAY构造函数会找到最佳的公分母(如果可能)。
很可能是表
exchange.kvwap_d1
中的某列(m1, m5, m15, m30, h1, h2, h4, d1, low, vwap, high
)具有数据类型**real
**(float4
)。(没有一列是float8
。)这将强制所构造数组的数据类型为real[]
。默认情况下,1577836800
作为real
数字的表示法是科学记数法:转换为json
保留了它。在将所有浮点输入填入数组之前,将其强制转换为
numeric
。或者使用
jsonb
而不是json
。jsonb
将数值数据转换为numeric
类型以在内部存储它们。手册:值得注意的一个语义无关紧要的细节是,在
jsonb
中,数字将根据底层numeric
类型的行为来打印,实际上这意味着使用**E
**符号输入的数字将不使用它来打印...