postgresql 创建JSON对象时,数字的显示会有所不同

wydwbb8l  于 2023-03-12  发布在  PostgreSQL
关注(0)|答案(1)|浏览(91)

我有以下功能:

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***的,它们是相同的数字。
为什么会这样呢?如何防止数字以科学记数法显示呢?

yc0p9oo0

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而不是jsonjsonb将数值数据转换为numeric类型以在内部存储它们。手册:

值得注意的一个语义无关紧要的细节是,在jsonb中,数字将根据底层numeric类型的行为来打印,实际上这意味着使用**E**符号输入的数字将不使用它来打印...

相关问题