[英]Postgres JSONB query simplification
我有一些工作代码从表单表中提取记录,其中 'mail@example.com' 在 JSONB 字段之一、 column_a
、 column_b
、 column_c
或column_d
显示为 JSON 值。
SELECT *
FROM forms f
WHERE exists (SELECT *
FROM jsonb_each_text(f.column_a) as e(ky,val)
WHERE e.val = 'mail@example.com')
UNION
SELECT *
FROM forms f
WHERE exists (SELECT *
FROM jsonb_each_text(f.column_b) as e(ky,val)
WHERE e.val = 'mail@example.com')
UNION
SELECT *
FROM forms f
WHERE exists (SELECT *
FROM jsonb_each_text(f.column_c) as e(ky,val)
WHERE e.val = 'mail@example.com')
UNION
SELECT *
FROM forms f
WHERE exists (SELECT *
FROM jsonb_each_text(f.column_d) as e(ky,val)
WHERE e.val = 'mail@example.com');
列中的 JSON 类似于:
{ "xyz":"mail@example.com", "def":"mail2@example.com", "lmn":"mail3@example.com" }
尽管代码有效,但它看起来高度重复/冗长。 鉴于我无法更改 JSON 结构,是否有更简洁的方法来构建此查询,以及我应该为这些列构建哪些索引以获得最佳性能?
为什么不使用or
?
SELECT f.*
FROM forms f
WHERE EXISTS (SELECT *
FROM jsonb_each_text(f.column_a) as e(ky,val)
WHERE e.val = 'mail@example.com'
) OR
EXISTS (SELECT *
FROM jsonb_each_text(f.column_b) as e(ky,val)
WHERE e.val = 'mail@example.com'
) OR
. . .
据推测,这也消除了重复消除的需要,因此查询也应该更快。
编辑:
如果需要源,可以使用相关子查询:
SELECT f.*
FROM (SELECT f.*,
EXISTS (SELECT *
FROM jsonb_each_text(f.column_a) as e(ky,val)
WHERE e.val = 'mail@example.com'
) as in_column_a,
EXISTS (SELECT *
FROM jsonb_each_text(f.column_b) as e(ky,val)
WHERE e.val = 'mail@example.com'
) as in_column_b,
. . .
FROM forms f
)
WHERE in_column_a OR in_column_b OR . . .
这不是很有效,因为它在找到匹配时不会短路评估。 另一方面,它列出了所有匹配的列。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.