我有这样的名字:'Foo [1] .Bar.Baz [2] .Foo.Bar.Bar [3]'我想在其中将方括号中的数字提取为数组 {1,2,3}。
目前我有这样的丑陋的东西:
select array_agg(digit) as digits from
(select unnest(regexp_matches) as digit from
(select * from regexp_matches('Foo[1].Bar.Baz[2].Foo.Bar.Bar[3]', '\[(\d+)\]', 'g')) t1) t2;
不幸的是,如果还有更多的字段,并且按照行的顺序将一个组弄混了。
有没有办法做到这一点?
完整的语句看起来像这样(只需要运行一次即可迁移某些数据)。
select device_tag_name, new_digits from
(select device_tag_id_pk, device_tag_name, array_agg(digit) as new_digits, dht.hmi_tag_id_pk, dht.digits as digits from (
select device_tag_id_pk,device_tag_name, unnest(regexp_matches(device_tag_name, '\[(\d+)\]', 'g')::int[]) as digit from "dim_DeviceTags" ddt) as subquery
join "map_HMIDevice" mhd on mhd.device_tag_id_fk = subquery.device_tag_id_pk
join "dim_HMITags" dht on mhd.hmi_tag_id_fk = dht.hmi_tag_id_pk
group by device_tag_id_pk, device_tag_name, dht.digits, dht.hmi_tag_id_pk) as t
where new_digits != digits;
结果看起来像这样:
| device_tag_name |新数字| | --------------------------------------- | --------- -| | Extr [1] .Hzne [8] .Ctrl.MF.Max.OA_Cnvl [4] | {8,1,4} | | Extr [1] .Hzne [8] .Ctrl.MF.Max.OA_Cnvl [3] | {1,3,8} | | Extr [1] .Hzne [8] .Ctrl.MF.Max.OA_Cnvl [2] | {8,2,1} | | Extr [1] .Hzne [8] .Ctrl.MF.Max.OA_Cnvl [1] | {8,1,1} | | Extr [1] .Hzne [8] .Ctrl.MF.Max.OA_Cnvl [2] | {8,2,1} | | Extr [1] .Hzne [8] .Ctrl.MF.Max.OA_Cnvl [1] | {8,1,1} |
将WITH ORDINALITY
指定为regexp_matches,然后使用该序数列对聚合进行排序。
select array_agg(digit order by ordinality desc) as digits from
(select unnest(regexp_matches) as digit, ordinality from
(select * from regexp_matches('Foo[1].Bar.Baz[2].Foo.Bar.Bar[3]', '\[(\d+)\]', 'g') with ordinality) t1) t2;
请注意,为了进行测试/演示,我颠倒了排序顺序,以便从视觉上将结果与原始结果区分开。
这里不需要您的UNNEST。由于您在正则表达式中只有一个捕获组,因此生成的匹配数组始终只有一个值。因此,除了取消嵌套之外,您还可以简单地使用方形bracets索引数组以获取唯一值:
select array_agg(digit order by ordinality desc) as digits from
(select regexp_matches[1] as digit, ordinality from regexp_matches('Foo[1].Bar.Baz[2].Foo.Bar.Bar[3]', '\[(\d+)\]', 'g') with ordinality) t1;