从 postgres 表中提取 json 数组给出错误:无法从标量中提取元素

2024-05-10

通过使用jsonb_array_elements()提取出来的函数jsonb来自 Postgres 的数据数组,它给出了错误:

无法从标量中提取元素

我认为这是因为NULL在返回调用中,添加了NULL检查状况但不工作。任何帮助表示赞赏。

   select id ,
   CASE
    WHEN report IS NULL OR 
         (report->'stats_by_date') IS NULL OR 
         (report->'stats_by_date'-> 'date') IS NULL then to_json(0)::jsonb
    ELSE jsonb_array_elements(report -> 'stats_by_date' -> 'date') 
    END AS Date
   from factor_reports_table

截断的 json 数组如下所示:

"stats_by_date": {"date": [16632, 16633, 16634, ...], "imps": [2418, 896, 1005...], ...}


重要的提示:从 Postgres 10 及更高版本开始,情况发生了变化,因此请根据您的数据库版本选择正确的解决方案。发生了什么变化?从 Postgres 10 开始,不允许在 CASE 语句中使用集合返回函数,并且jsonb_array_elements就是这样一个函数。

Postgres 10 之前的版本

在您的数据中必须有一些标量值而不是内部数组date key.

您可以使用以下命令来识别特定键的类型jsonb_typeof()然后将其包裹在一个CASE陈述。

考虑下面的标量和数组示例作为输入集:

select 
  case when jsonb_typeof(jsonb_column->'stats_by_date'->'date') = 'array' 
       then jsonb_array_elements(jsonb_column->'stats_by_date'->'date') 
       else jsonb_column->'stats_by_date'->'date' 
  end as date
from (
  select '{"stats_by_date": {"date": 123}}'::jsonb -- scalar (type: 'number')
  union all 
  select '{"stats_by_date": {"date": [456]}}'::jsonb -- array (type: 'array')
  ) foo(jsonb_column);

Result

 date
------
 123
 456

因此,您的查询需要像这样编写来处理这种情况:

select id,
  case when jsonb_typeof(jsonb_column->'stats_by_date'->'date') = 'array' 
       then jsonb_array_elements(jsonb_column->'stats_by_date'->'date') 
       else jsonb_column->'stats_by_date'->'date' 
  end as date
from factor_reports_table

Postgres 版本 10+

由于 Pg10 不允许使用集合返回函数,因此我们需要编写更多代码来实现相同的目的。设置返回函数意味着函数调用可以输出多行,并且不允许在 CASE 语句中使用。简单的说,Postgres 希望我们为此编写明确的代码。

逻辑与上面相同(指10之前的pg版本),但我们将分两步而不是一步进行。

首先,我们需要找到两种类型的共同表示:数字和数组。我们可以用一个数字组成一个数组,因此数组将是一个不错的选择。我们所做的是为每种情况构建一个数组(阅读评论):

  case when jsonb_typeof(jsonb_column->'stats_by_date'->'date') = 'array' -- if array
       then jsonb_column->'stats_by_date'->'date' -- leave it as it is
       else jsonb_build_array(jsonb_column->'stats_by_date'->'date') -- if not array, build array
  end as date

第二步是将我们的数据类型转换包装在一个语句中,使用WITH子句,然后使用函数调用从中选择FROM像这样的子句:

with json_arrays as (
select 
  case when jsonb_typeof(jsonb_column->'stats_by_date'->'date') = 'array' 
       then jsonb_column->'stats_by_date'->'date'
       else jsonb_build_array(jsonb_column->'stats_by_date'->'date')
  end as date
from (
  select '{"stats_by_date": {"date": 123}}'::jsonb -- scalar (type: 'number')
  union all 
  select '{"stats_by_date": {"date": [456]}}'::jsonb -- array (type: 'array')
  ) foo(jsonb_column)
)
select t.date
from 
  json_arrays j -- this is refering to our named WITH clause
, jsonb_array_elements(date) t(date) -- call function to get array elements
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 postgres 表中提取 json 数组给出错误:无法从标量中提取元素 的相关文章

随机推荐

  • OVER ORDER BY 中的多个列

    有没有办法在 OVER ORDER BY 子句中指定多个列 SELECT ROW NUMBER OVER ORDER BY A Col1 AS ID FROM MyTable A 上面的方法工作正常 但尝试添加第二列不起作用 SELECT
  • 尝试在本地主机上测试我的 php 文件,但只出现一个空白页面,没有错误消息

    我正在运行 Apache 和 mySQL 因为我检查了所有日志 似乎没有任何错误 我的目标是每当有新的表单条目时就向特定地址发送电子邮件 我对后端和 PHP 缺乏经验 所以我不太确定哪里出了问题 任何帮助将不胜感激
  • 哪种 Java DOM 包装器是最好或最受欢迎的? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 使用脚本自动输入 SSH 密码

    我需要创建一个自动向 OpenSSH 输入密码的脚本ssh client 假设我需要通过 SSH 进入myname somehost用密码a1234b 我已经尝试过 bin myssh sh ssh myname somehost a123
  • 如何在高速缓存中存储图像

    我对此完全空白 我想从 URL 下载图像 并且必须将其存储在内部 以便下次我不需要连接到网络 而是从缓存中检索它 但我不知道该怎么做 谁能帮我提供一个代码片段 import java io BufferedInputStream impor
  • Python time.sleep - 永不醒来

    我认为这将是那些简单的问题之一 但它让我感到困惑 停止媒体 我是对的 找到了解决方案 查看答案 我正在使用 Python 的单元测试框架来测试多线程应用程序 很好而且很直接 我有 5 个左右的工作线程监视一个公共队列 以及一个为它们制作工作
  • 如何将reportlab与Google应用程序引擎一起使用

    我无法在谷歌应用程序引擎下正确导入reportlab 根据以下guide http blog notdot net 2010 04 Generating PDFs on App Engine Python and introducing M
  • useEffect 中的 useState 不更新状态

    我是 React Hooks 新手 正在使用 React 16 13 1 我要实施Auth能够处理登录的组件 但似乎没有更新状态currentUser正确地 尽管setCurrentUser使用响应对象调用 这段代码有什么问题 import
  • JavaScript:嵌套循环?

    我想实现这样的动画 序列 动画以循环开始 想象一下car从 x1 移动到 x2 然后暂停 1 秒 然后再次播放动画 想象一下car从 x2 移动到 x3 等 the car循环是通过向汽车左侧添加 1px 来实现的 值 但我无法弄清楚嵌套循
  • 无法使用数据源配置向导在 Web 项目中添加数据源

    Problem 我想将报告 rdlc 添加到我的 Web 项目中 我需要报表使用对象数据源 而不是直接连接到数据库 我的问题是 当我运行 报告向导 或向报告添加新数据集时 数据源配置向导 only允许我使用数据库 然而 在图书馆项目中数据源
  • C# 中不区分大小写的替换不使用正则表达式?

    有没有一种方法可以在不使用 C 中的正则表达式的情况下对字符串进行不区分大小写的替换 像这样的东西 string x Hello x x Replace hello hello world 你可以尝试类似的东西 string str Hel
  • 如何在IOS中使用“*”字符进行呼叫(拨号)?

    我希望用 字符来调用 例如 gt 711313 目前 我正在使用这段代码 NSString str NSString stringWithFormat tel tmp UIApplication sharedApplication open
  • 选择不带 FROM 但有多于一行的选择

    如何在不从现有表中进行选择的情况下生成 2 行 2 列的表 我正在寻找的是一个返回的选择语句 e g id value 1 103 2 556 Use UNION http dev mysql com doc refman 5 0 en u
  • scikit-learn RandomForestClassifier 中的子样本大小

    如何控制用于训练森林中每棵树的子样本的大小 根据 scikit learn 的文档 随机森林是一种适合许多决策的元估计器 数据集的各个子样本上的树分类器并使用 平均以提高预测准确性并控制过度拟合 子样本大小始终与原始输入样本相同 大小 但如
  • Spring Boot中使用自定义令牌进行身份验证

    我需要保护我的 Spring Boot 应用程序 这就是我所拥有的 一个 Spring Boot 应用程序 公开了一些 REST API 与公开的 api 通信的前端 前端发送用于身份验证的自定义身份验证令牌 存储自定义身份验证令牌的数据库
  • postgreSQL 将分区表(带插入触发器)从一台服务器转储和恢复到另一台服务器

    尝试将分区表从一台服务器转储到 PostgreSQL 9 4 5 中的另一台服务器 对 postgres 相当陌生 并继承了该项目 如果需要更多背景信息 请告诉我 dbname gt SELECT COUNT id FROM parent
  • 使用数学符号注释 Adob​​e Reader PDF

    我阅读的许多数学教科书和其他文献都是 PDF 格式 因此我经常使用 Adob e Reader 注释工具对它们进行注释 我确实找到了一个有用的指南 http cjasn asnjournals org site misc annotatin
  • SQL:两个没有完整列匹配的表的并集

    我有一个table A其中有一组列A1 A2和一个具有一组列的 table bB1 B2 碰巧的是A2 B1但其余列不匹配 也不应该匹配 我想附加表格 所以我使用UNION ALL 对于不匹配的列 我使用null as COLUMN NAM
  • Moq - 是否可以在不使用 It.IsAny 的情况下设置模拟

    我一直使用 Moq 进行单元测试 有时我会嘲笑有很多参数的方法 想象一下这样的方法 public class WorkClient public void DoSomething string itemName int itemCount
  • 从 postgres 表中提取 json 数组给出错误:无法从标量中提取元素

    通过使用jsonb array elements 提取出来的函数jsonb来自 Postgres 的数据数组 它给出了错误 无法从标量中提取元素 我认为这是因为NULL在返回调用中 添加了NULL检查状况但不工作 任何帮助表示赞赏 sele