Sql Postgres Json(b)int数组包含任何数组值

Sql Postgres Json(b)int数组包含任何数组值,sql,json,postgresql,jsonb,Sql,Json,Postgresql,Jsonb,TLDR:如何查找包含给定数组/列表中一个数字的json数字数组的每个记录。 好的,我试了很多,读了很多其他的文章,但是我还没有找到一个有效的解决方案。我想在Postgres中找到一些JSON对象。它们包含多项选择的索引 对象: [{"id": 5, "list": [1, 2, 3]}, {"id": 6, "list": [4, 5, 6]}] 我需要选择所有包含项目1或5的对象。现在,我只能检查一个值 SELECT '[1, 2, 3, 4]'::jsonb @> '3'::jso

TLDR:如何查找包含给定数组/列表中一个数字的json数字数组的每个记录。

好的,我试了很多,读了很多其他的文章,但是我还没有找到一个有效的解决方案。我想在Postgres中找到一些JSON对象。它们包含多项选择的索引

对象:

[{"id": 5, "list": [1, 2, 3]}, {"id": 6, "list": [4, 5, 6]}]
我需要选择所有包含项目1或5的对象。现在,我只能检查一个值

SELECT '[1, 2, 3, 4]'::jsonb @> '3'::jsonb as result;
或者如果两者都存在:

SELECT '[1,2,3,4]'::jsonb @> '[1, 2]'::jsonb as result;
或者,有趣的是,如果我有一个字符串数组,我可以做我需要的事情:

SELECT '["1","2","3","4"]'::jsonb ?| array['1', '5'] as result;
如何将其应用于JSON数字数组?我试着使用int[]和其他很多东西。什么都没用。我要么需要将数字数组转换为文本数组来使用它,要么为右侧找到正确的类型转换。这也不起作用:
?|数组[1,5]::text[]

解决方案1:

嗯,我和毛村想到的第一件事,使用
,看起来仍然是最快最简单的解决方案

解决方案2:

我终于找到了一种缩短时间的方法(就像我认为它应该有效的那样),但这是一个铸造地狱(也是9.4+),看起来并不漂亮:

SELECT array_to_json(翻译('[1,2,3,4]'::jsonb::text,'[]','{}')::text[])::jsonb?|数组['1','5']作为结果


基本上将整数转换为字符串。

您可以使用

t=# SELECT '[1, 2, 3, 4]'::jsonb @> '3'::jsonb OR '[1, 2, 3, 4]'::jsonb @> '5'::jsonb as result;
 result
--------
 t
(1 row)
或将未列出的jsonb数组聚合到int数组,以便在其相交时进行比较:

t=# with c(j) as (values('[1, 2, 3, 4]'::jsonb))
, a as (select j,jsonb_array_elements(j) ja from c)
select array_agg(ja), j, array_agg(ja::text::int) && array[5,4] from a group by j;
 array_agg |      j       | ?column?
-----------+--------------+----------
 {1,2,3,4} | [1, 2, 3, 4] | t
(1 row)

在你的例子中。我看不到任何优雅的较短解决方案…

您可以使用

t=# SELECT '[1, 2, 3, 4]'::jsonb @> '3'::jsonb OR '[1, 2, 3, 4]'::jsonb @> '5'::jsonb as result;
 result
--------
 t
(1 row)
或将未列出的jsonb数组聚合到int数组,以便在其相交时进行比较:

t=# with c(j) as (values('[1, 2, 3, 4]'::jsonb))
, a as (select j,jsonb_array_elements(j) ja from c)
select array_agg(ja), j, array_agg(ja::text::int) && array[5,4] from a group by j;
 array_agg |      j       | ?column?
-----------+--------------+----------
 {1,2,3,4} | [1, 2, 3, 4] | t
(1 row)

在你的例子中。我看不到任何简洁的解决方案…

您可以使用jsonb_array_元素,转换为文本,然后转换为int并与array_agg组合

WITH j AS (SELECT array_agg(h), othercol, thirdcol a FROM
  (SELECT jsonb_array_elements('[53,22,41,23]')::text::int h, othercol,
    thirdcol) AS j GROUP BY othercol, thirdcol)
SELECT othercol, thirdcol FROM j WHERE j.a && ARRAY[44,13,12,41];

不完全优雅,特别是当你考虑< <代码>组> <代码>语句

时,可以使用JSONBJARARYAY元素,将其转换为文本,然后再输入int,并与ArayaAGG.

结合。
WITH j AS (SELECT array_agg(h), othercol, thirdcol a FROM
  (SELECT jsonb_array_elements('[53,22,41,23]')::text::int h, othercol,
    thirdcol) AS j GROUP BY othercol, thirdcol)
SELECT othercol, thirdcol FROM j WHERE j.a && ARRAY[44,13,12,41];

不完全优雅,特别是当你考虑<<代码>组的语句

时,你也可以这样做:

select translate('[1,2,3]', '[]','{}')::int[] && ARRAY[1,3]
您也可以这样做:

select translate('[1,2,3]', '[]','{}')::int[] && ARRAY[1,3]

当然,使用
不是一个选项<代码>选择“[1,2,3,4]”::jsonb@>'3'::jsonb或“[1,2,3,4]”::jsonb@>'5'::jsonb作为结果
是我想到的第一个解决方案,但由于选择了很多选项,它肯定会破坏查询。当然,这只是一个非常复杂的查询的一部分:)但是,是的,现在,它是最干净、最快的解决方案。当然,使用
不是一个选项<代码>选择“[1,2,3,4]”::jsonb@>'3'::jsonb或“[1,2,3,4]”::jsonb@>'5'::jsonb作为结果
是我想到的第一个解决方案,但由于选择了很多选项,它肯定会破坏查询。当然,这只是一个非常复杂的查询的一部分:)但是,是的,现在,它像是最干净、最快的解决方案。这确实是我没有想到的,但正如你所说的:
分组方式并不理想。但是谢谢!这确实是我没有想到的,但正如你所说的:
分组方式并不理想。但是谢谢!是的,
解决方案是我想到的第一件事,但我认为会有一些简短/优雅的解决方案。我接受了这一点,因为它仍然是最快、最简单的解决方案。目前:)是的,
解决方案是我想到的第一件事,但我认为会有一些更短/优雅的解决方案。我接受了这一点,因为它仍然是最快、最简单的解决方案。目前:)