在我的表中,我有专栏facebook,我存储了facebook数据(评论数,分享数等),而且它是一个数组。例如:
{{total_count,14},{comment_count,0},{comment_plugin_count,0},{share_count,12},{reaction_count,2}}
现在我试图选择facebook total_count介于5到10之间的行。我已经尝试过了:
SELECT * FROM pl where regexp_matches(array_to_string(facebook, ' '), '(\d+).*')::numeric[] BETWEEN 5 and 10;
但是我收到了错误:
错误:运算符不存在:numeric []> = integer
有什么想法吗?
答案 0 :(得分:1)
无需将数组转换为文本并使用regexp。您可以访问数组的特定元素,例如:
with pl(facebook) as (
values ('{{total_count,14},{comment_count,0},{comment_plugin_count,0},{share_count,12},{reaction_count,2}}'::text[])
)
select facebook[1][2] as total_count
from pl;
total_count
-------------
14
(1 row)
您的查询可能如下所示:
select *
from pl
where facebook[1][2]::numeric between 5 and 10
更新。如果您使用单词null
而不是空字符串''''
,则可以避免评论中描述的问题。
with pl(id, facebook) as (
values
(1, '{{total_count,14},{comment_count,0}}'::text[]),
(2, '{{total_count,null},{comment_count,null}}'::text[]),
(3, '{{total_count,7},{comment_count,10}}'::text[])
)
select *
from pl
where facebook[1][2]::numeric between 5 and 10
id | facebook
----+--------------------------------------
3 | {{total_count,7},{comment_count,10}}
(1 row)
然而,如果没有额外的评论,留下你的问题是不公平的。这个案例适合作为演讲的一个例子如何不在Postgres中使用数组。你至少有几个更好的选择。最高效和最自然的是简单地使用常规整数列:
create table pl (
...
facebook_total_count integer,
facebook_comment_count integer,
...
);
如果由于某种原因需要将此数据与表中的其他数据分开,请使用主表的外键创建一个新的辅助表。
如果由于一些神秘的原因你必须将数据存储在一个列中,请使用jsonb
类型,例如:
with pl(id, facebook) as (
values
(1, '{"total_count": 14, "comment_count": 0}'::jsonb),
(2, '{"total_count": null, "comment_count": null}'::jsonb),
(3, '{"total_count": 7, "comment_count": 10}'::jsonb)
)
select *
from pl
where (facebook->>'total_count')::integer between 5 and 10
hstore
可以替代jsonb
。
所有这些方式都比您当前的模型更容易维护和更有效。是时候走向光明的一面了。