从jsonb数组中的对象加入值

时间:2019-04-21 08:50:54

标签: json postgresql

我有一个看起来像这样的表:

stone_data     | ...
---------------+----
{[...], [...]} | ...

我的石头数据是jsonb,看起来像这样:

[{
  "Quantity": 2,
  "SKU": "abc123"
}, {
  "Quantity": 1,
  "SKU": "def456"
}]

然后我有了另一个看起来像这样的表:

sku (string) | ... | ...
-------------+-----+----
abc123       | ... | ...
def456       | ... | ...

第一个表称为settings,第二个表称为accent_stones。我正在尝试从settings中选择一些行,并在石头sku上加入accent_stones。我已经接近了,但无法完全正常工作:

SELECT *
FROM settings
LEFT JOIN accent_stones
ON accent_stones.sku = ANY(jsonb_array_elements(stone_data) ->> 'SKU');

我还想知道这是否是FULL JOIN所需要的,但是我还没有弄清楚,因为我还没有使联接起作用。我收到此错误:

ERROR: op ANY/ALL (array) requires array on right side

我理解该错误,但是我不知道该如何使用ANY以外的东西,或者将结果集转换为数组。

2 个答案:

答案 0 :(得分:2)

好吧,jsonb_array_elements()返回一个集合,而不是一个数组。因此,您可以使用IN和一个子查询。

SELECT *
       FROM settings
            LEFT JOIN accent_stones
                      ON accent_stones.sku IN (SELECT e->>'SKU'
                                                      FROM jsonb_array_elements(stone_data) ja (e));

db<>fiddle

答案 1 :(得分:1)

您最好在from子句中交叉连接jsonb_array_elements。这将允许您在select子句中引用json的元素。

SELECT s.* , j->>'SKU' ,j->> 'Quantity',a.* 
  FROM settings s cross join jsonb_array_elements(stone_data) as j
     LEFT JOIN accent_stones a ON a.sku = j->> 'SKU'

DEMO