将 jsonb_path_query_array 结果与另一个数组进行比较(忽略排序)
Compare jsonb_path_query_array result with another array (ignoring ordering)
我有一个 table table1
看起来像这样:
sentence data
good [{"pred": "yes", 'prob': 0.6}, {"pred": "maybe", "prob": 0.4}, {"pred": "another", "prob": 0.7}]
bad [{"pred": "unexpected", "prob": 0.4}, {"pred": "uncool", "prob": 0.3}]
和另一个 table table2
看起来像:
sentence real_values
good ["another", "yes"]
bad ["no"]
我想输出一个布尔值列,表示数组 real_values
中的值集是否与 data
中的 pred
值集匹配(仅比较 prob
中的值>= 0.5)
因此,为此,结果将是:
sentence | preds | real_values | is_match
-----------+-------
good | ['yes', 'another'] | ["another", "yes"] | true
bad | [] | ["no"] | false
(2 rows)
这是我到目前为止尝试过的方法:
SELECT sentence,
jsonb_path_query_array(data, '$[*] ? (@.prob >= 0.5).pred') as preds,
table2.real_values,
(
ARRAY(SELECT jsonb_path_query_array(data, '$[*] ? (@.prob >= 0.5).pred')) <@ ARRAY(SELECT table2.real_values)
AND ARRAY(SELECT jsonb_path_query_array(data, '$[*] ? (@.prob >= 0.5).pred')) @> ARRAY(SELECT table2.real_values)
) AS is_match
FROM table1
CROSS JOIN table2
WHERE table1.sentence = table2.sentence
GROUP BY table1.sentence, table2.real_values, table1.preds
;
它 returns 我:
sentence | preds | real_values | is_match
-----------+-------
good | ['yes', 'another'] | ['another', 'yes'] | false
bad | [] | ['no'] | false
对于第一种情况,is_match
应该是正确的,但事实并非如此。但是,当数组中只有 1 个元素时它确实有效,不确定查询有什么问题。
您不需要将 JSONB 值转换为本机数组。 @>
运算符也适用于 JSONB 值。
select t1.sentence,
jsonb_path_query_array(t1.data, '$[*] ? (@.prob >= 0.5).pred') as preds,
t2.real_values,
jsonb_path_query_array(t1.data, '$[*] ? (@.prob >= 0.5).pred') @> t2.real_values as is_match
from table1 t1
join table2 t2 on t1.sentence = t2.sentence
我有一个 table table1
看起来像这样:
sentence data
good [{"pred": "yes", 'prob': 0.6}, {"pred": "maybe", "prob": 0.4}, {"pred": "another", "prob": 0.7}]
bad [{"pred": "unexpected", "prob": 0.4}, {"pred": "uncool", "prob": 0.3}]
和另一个 table table2
看起来像:
sentence real_values
good ["another", "yes"]
bad ["no"]
我想输出一个布尔值列,表示数组 real_values
中的值集是否与 data
中的 pred
值集匹配(仅比较 prob
中的值>= 0.5)
因此,为此,结果将是:
sentence | preds | real_values | is_match
-----------+-------
good | ['yes', 'another'] | ["another", "yes"] | true
bad | [] | ["no"] | false
(2 rows)
这是我到目前为止尝试过的方法:
SELECT sentence,
jsonb_path_query_array(data, '$[*] ? (@.prob >= 0.5).pred') as preds,
table2.real_values,
(
ARRAY(SELECT jsonb_path_query_array(data, '$[*] ? (@.prob >= 0.5).pred')) <@ ARRAY(SELECT table2.real_values)
AND ARRAY(SELECT jsonb_path_query_array(data, '$[*] ? (@.prob >= 0.5).pred')) @> ARRAY(SELECT table2.real_values)
) AS is_match
FROM table1
CROSS JOIN table2
WHERE table1.sentence = table2.sentence
GROUP BY table1.sentence, table2.real_values, table1.preds
;
它 returns 我:
sentence | preds | real_values | is_match
-----------+-------
good | ['yes', 'another'] | ['another', 'yes'] | false
bad | [] | ['no'] | false
对于第一种情况,is_match
应该是正确的,但事实并非如此。但是,当数组中只有 1 个元素时它确实有效,不确定查询有什么问题。
您不需要将 JSONB 值转换为本机数组。 @>
运算符也适用于 JSONB 值。
select t1.sentence,
jsonb_path_query_array(t1.data, '$[*] ? (@.prob >= 0.5).pred') as preds,
t2.real_values,
jsonb_path_query_array(t1.data, '$[*] ? (@.prob >= 0.5).pred') @> t2.real_values as is_match
from table1 t1
join table2 t2 on t1.sentence = t2.sentence