在Postgres的json列中将LocalDate转换为时间戳

时间:2018-09-11 13:46:43

标签: json postgresql postgresql-9.5

我必须迁移PostgresDB 9.5中的列。

表名称为testtable,相关列为examplecolumn。

在examplecolumn中,我有以下JSON数组:

[{"key":"id","before":null,"after":4371},
{"key":"status","before":null,"after":1},
{"key":"startDate","before":null,"after":1514761200000},
{"key":"endDate","before":null,"after":1546297199000},
{"key":"billingDate","before":null,"after":{"year":2018,"month":"JANUARY","dayOfMonth":15,"dayOfWeek":"MONDAY","era":"CE","dayOfYear":15,"leapYear":false,"monthValue":1,"chronology":{"calendarType":"iso8601","id":"ISO"}}}]

我想将带有“ billingDate”的孩子转换为以下格式的时间戳:

[{"key":"id","before":null,"after":4371},
{"key":"status","before":null,"after":1},
{"key":"startDate","before":null,"after":1514761200000},
{"key":"endDate","before":null,"after":1546297199000},
{"billingDate":1515974400}]

我想保留其他所有东西。首先,我试图像这样获得这些行。

SELECT *, examplecolumn::json->4->'after' as export
FROM testtable
WHERE examplecolumn like '%after":{%';

但是我无法使用固定索引(例如4)来执行此操作,并且我不知道哪个行具有此LocalDate的子对象,这就是为什么我写了此从句。

我该怎么做?我用了几个Postgres JSON函数尝试了很多次,但是我受够了。

谢谢。

1 个答案:

答案 0 :(得分:0)

我不清楚问题是否是根据问题的标题将数据转换为时间戳,还是根据问题提取数据。所以这个答案是关于提取数据的。

首先,CTE只是将JSON数组中各项的顺序随机化,以表明它绕开了索引问题。显然,您将改为在表上执行查询。然后,带有“ billingDate”的项目仅包含在偶数结果中;奇数个包含其余的JSON项,但不包括该项。

WITH cte AS (
        SELECT ('[' || STRING_AGG(CASE WHEN id = 2 THEN CASE WHEN g % 2 = 0 THEN j::TEXT END ELSE j::TEXT END, ',' ORDER BY RANDOM()) || ']')::JSON AS j
        FROM (
                VALUES
                (1, '{"key":"id","before":null,"after":4371}'),
                (1, '{"key":"status","before":null,"after":1}'),
                (1, '{"key":"startDate","before":null,"after":1514761200000}'),
                (1, '{"key":"endDate","before":null,"after":1546297199000}'),
                (2, '{"key":"billingDate","before":null,"after":{"year":2018,"month":"JANUARY","dayOfMonth":15,"dayOfWeek":"MONDAY","era":"CE","dayOfYear":15,"leapYear":false,"monthValue":1,"chronology":{"calendarType":"iso8601","id":"ISO"}}}')
        ) AS v(id, j), generate_series(1, 10) AS g
        GROUP BY g
)
SELECT j, (SELECT je->'after' FROM JSON_ARRAY_ELEMENTS(j) AS je WHERE je->>'key' = 'billingDate' AND (je->>'after') IS NOT NULL) AS export
FROM cte

结果:

enter image description here

如果您只想获取具有“ billingDate”的项目,则可以从问题中添加WHERE子句:

WITH cte AS (
        SELECT ('[' || STRING_AGG(CASE WHEN id = 2 THEN CASE WHEN g % 2 = 0 THEN j::TEXT END ELSE j::TEXT END, ',' ORDER BY RANDOM()) || ']')::JSON AS j
        FROM (
                VALUES
                (1, '{"key":"id","before":null,"after":4371}'),
                (1, '{"key":"status","before":null,"after":1}'),
                (1, '{"key":"startDate","before":null,"after":1514761200000}'),
                (1, '{"key":"endDate","before":null,"after":1546297199000}'),
                (2, '{"key":"billingDate","before":null,"after":{"year":2018,"month":"JANUARY","dayOfMonth":15,"dayOfWeek":"MONDAY","era":"CE","dayOfYear":15,"leapYear":false,"monthValue":1,"chronology":{"calendarType":"iso8601","id":"ISO"}}}')
        ) AS v(id, j), generate_series(1, 10) AS g
        GROUP BY g
)
SELECT j, (SELECT je->'after' FROM JSON_ARRAY_ELEMENTS(j) AS je WHERE je->>'key' = 'billingDate' AND (je->>'after') IS NOT NULL) AS export
FROM cte
WHERE j::TEXT LIKE '%after":{%'

结果:

enter image description here