PostgreSQL中存在jasonb的字段,里面是可以支持无限扩展的,目前所在SaaS平台的公司平台架构充分利用了这一点,直接在jasonb类型里面增加字段,调整很是零活。甚至新建的表都不需要实体表,完全在这种字段里实现。
回归正题,遇到的问题是某一个列叫ext,也就是今天说到的jsonb类型的字段。
他里面的product字段是多选字段,存储的是product表的id,用逗号分隔开来。
举例:
拜访表中,
call.ext->>product = ["2323242423231111","2323242423231112","2323242423231113","2323242423231114"]
产品表中,
只有两列:id和name
此时通过如何拆分call中的product字段成为一个难题,首先是多选,其次选择的个数不固定(id的长度是一定的)。
目前已经集思广益发现了三种解决方案:
方案一:
SELECT
event.NAME "活动名称",
LOCATION "活动地点",
UNNEST (
string_to_array(
rtrim( ltrim( REPLACE ( REPLACE ((coalesce (call.ext ->> 'product','000')), '"', '' ), ' ', '' ), '[' ), ']' ),
','
)) as "产品"
from call
方案二(最骚气的一种,有方法竟然支持in操作):
select
string_agg(name, ',')
from
product
where
id::text in (
select jsonb_array_elements_text((c.ext->>'product')::jsonb)
)
方案三(按字段长度截取,不太智能,需要限制最长的范围):
select u.id u_id,
(u.ext->>'related_product') p0,
substr((u.ext->>'related_product'),3,16),
substr((u.ext->>'related_product'),23,16),
substr((u.ext->>'related_product'),43,16),
substr((u.ext->>'related_product'),63,16),
substr((u.ext->>'related_product'),83,16),
p1.name p1name,
p2.name p2name,
p3.name p3name,
p4.name p4name,
p5.name p5name,
concat(p1.name,',',p2.name,',',p3.name,',',p4.name,',',p5.name) as p6
from user_info u left join
product p1
on
substr((u.ext->>'related_product'),3,16)=text(p1.id) and p1.is_deleted = false
left join product p2
on
substr((u.ext->>'related_product'),23,16)=text(p2.id) and p2.is_deleted = false
left join product p3
on
substr((u.ext->>'related_product'),43,16)=text(p3.id) and p3.is_deleted = false
left join product p4
on
substr((u.ext->>'related_product'),63,16)=text(p4.id) and p4.is_deleted = false
left join product p5
on
substr((u.ext->>'related_product'),83,16)=text(p5.id) and p5.is_deleted = false
where concat(p1.name,',',p2.name,',',p3.name,',',p4.name,',',p5.name) <> ''