【问题标题】:Postgresql extract multiple values into different columnsPostgresql 将多个值提取到不同的列中
【发布时间】:2021-12-21 01:23:47
【问题描述】:

我需要将信息转换成列,但是在某些情况下,一个答案可以有多个值。

我设法使用以下代码将答案连接到一个列表中:

'{' || ARRAY_TO_STRING(ARRAY_AGG('"' || Question || '":' || Answer),',') || '}' AS key_value

然后使用此列我可以提取它:

CAST(COALESCE(key_value::JSON ->> 'consumption_soda','0') AS INTEGER) AS soda_consumption,
CAST(COALESCE(key_value::JSON ->> 'consumption_water','0') AS INTEGER) AS water_consumption

但是,当我想提取 soda_painpoints 时,它只会返回第一个值。 你能帮我找到我的问题的答案吗?

!!!!更新: 刚刚在原始数据中发现一些答案是重复的,必须过滤掉。必须始终使用最新的答案,除非这两个答案发生在不同的月份。然后两者都应该被提取。 在一个单元格中,可能有多个答案需要分成几列。或者答案可以在不同的行中。

原始数据表的起始格式:

我想要一个像这样的平坦输出,其中痛点最多可以有 8 个值 -> 8 soda_painpoints 列:

【问题讨论】:

  • 这些实际上不是NULL,只是在excel中分开以便于查看。

标签: arrays json postgresql coalesce


【解决方案1】:

首先,要将答案连接到 jsonb 对象中,您应该使用 jsonb_object_agg(Question, Answer) AS key_value 而不是 '{' || ARRAY_TO_STRING(ARRAY_AGG('"' || Question || '":' || Answer),',') || '}' AS key_value

那么soda_painpoints 问题的答案“1 5 8 7”似乎是一个字符串,它连接了一个由空格字符分隔的整数列表(1、5、8、7)。在这种情况下,您可以将 Answer 存储为简单的 jsonb 数值或 jsonb 数组,具体取决于 Answer 值的类型:

SELECT jsonb_object_agg( Question
                       , CASE 
                           WHEN jsonb_typeof(to_jsonb(Answer)) = 'number'
                           THEN Answer :: text
                           ELSE regexp_split_to_array(Answer, '\s+') :: text
                         END
                       ) AS key_value

这样做,与键 soda_painpoints 关联的值将是一个 jsonb 整数数组。

【讨论】:

  • 感谢代码,我现在检查了它,但它返回错误:错误:CASE类型整数[]和整数无法匹配...表中的所有列都存储为TEXT(问题和答案)可能是什么问题?
  • 确实,不可能在同一个CASE 中返回各种数据类型。因此,我在创建 jsonb 对象之前将所有答案转换为文本时更新了答案。如果您不介意将答案作为文本存储在 jsonb 对象中,此解决方案应该没问题。
  • 我更新了问题,因为我刚刚发现数据存在几个问题。感谢您修改后的代码,它可以正常工作,但是我很难找到有关如何从 JSON 数据中提取值的解决方案。也许 JSON 甚至不是这个问题的最佳解决方案。我欢迎你的建议。
猜你喜欢
  • 2017-09-18
  • 1970-01-01
  • 2021-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-27
  • 1970-01-01
相关资源
最近更新 更多