【问题标题】:How to select rows where jsonb overlaps an array of integer and text? (PostgreSQL)如何选择jsonb与整数和文本数组重叠的行? (PostgreSQL)
【发布时间】:2021-05-28 18:25:18
【问题描述】:

标题可能听起来不太清楚,所以这里是一个示例场景。

这是一个名为test的表。

 id |         json (this is "jsonb")         
----+----------------------
  1 | [0]
  2 | [1, 2, 3]
  3 | [4]
  4 | ["4"]
  5 | ["5", "6"]
  6 | ["5", "6", "7", "8"]

现在,您必须选择json 包含数组中至少一个元素的行

如果你运行select * from test where json::jsonb ?| array['4', '8', '10'];...

 id |         json         
----+----------------------
  4 | ["4"]
  6 | ["5", "6", "7", "8"]

如您所见,ID 3 的行被遗漏了。这是因为 ID 为 3 的json 是一个整数数组。

如果你把上面的语句改写成select * from test where json::jsonb ?| array[4, '8', '10'];...

ERROR:  operator does not exist: jsonb ?| integer[]
LINE 1: select * from test where json::jsonb ?| array[4, '8', '10'];
                                             ^
HINT:  No operator matches the given name and argument types. You might need to add explicit type casts.

?| 运算符似乎与整数不兼容。

是否可以选择jsonb(由整数和文本混合而成)与数组重叠的行?我从the doc 找不到任何功能来实现这一点。

我不是数据库专家,所以任何想法都将不胜感激!

【问题讨论】:

  • 这些值是否总是数字?可能是文本格式
  • 您使用 Postgres 12 或更高版本吗? JSON path 应该可以轻松搞定

标签: postgresql


【解决方案1】:

AFAIK 没有内置函数来完成它。但是您可以使用下面的技巧来根据您的要求使用?| 运算符。请注意?| 的右操作数必须是text[]。所以试试这个查询:

select id, json_ from (
select 
t1.id, 
t1.json_,
jsonb_agg(val) "val_" from 
test t1, jsonb_array_elements_text(json_) t(val)
group by 1,2) tab
where 
val_::jsonb ?| array['4', '8', '10']

DEMO

【讨论】:

    【解决方案2】:

    您可以使用EXISTS 子句对数组元素进行子查询:

    SELECT *
    FROM demo
    WHERE EXISTS(
      SELECT 1
      FROM jsonb_array_elements(data) AS val
      WHERE val IN ('4', '8', '10', '"4"', '"8"', '"10"')
    )
    

    (Online demo)

    注意IN 在此处比较jsonb 值,如果您不想同时指定整数和字符串,也可以将值转换为您想要的任何值并进行比较。

    【讨论】:

    • 感谢您的建议...但是数组应该是动态的(抱歉我没有提到它),所以它不能被硬编码
    • @Hiroki 数组的动态是什么?请编辑您的问题。
    猜你喜欢
    • 2019-10-27
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 2022-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多