Zhl*_*tam 3 postgresql select array postgresql-9.2
我有 PostgreSQL 9.2 数据库和一个表:
id integer,
allowed_types character varying(255)`
Run Code Online (Sandbox Code Playgroud)
样本数据如下:
id allowed_types
1 3,4,5,13,14
Run Code Online (Sandbox Code Playgroud)
如何从中删除4和5,allowed_types
其中以逗号分隔的 varchar 列表?
删除后,结果应该是allowed_types = 3,13,14
。
该表上有许多记录,每个记录allowed_types
可以包含不同的数字,用逗号分隔。
我考虑过string_to_array()
and array_remove()
,但array_remove()
还没有在 9.2 版中。
正则表达式的概念证明:
SELECT trim(regexp_replace(',' || '3,4,5,13,14' || ',', ',(4|5)(?=,)', '', 'g'), ',');
Run Code Online (Sandbox Code Playgroud)
返回:
3,13,14
Run Code Online (Sandbox Code Playgroud)
在开始和结束时填充逗号以覆盖极端情况。正则表达式',(4|5)(?=,)'
解释:
,
... 文字逗号
(4|5)
... 两个分支:4 或 5
(?=,)
...正向预测:下一个字符是文字逗号
需要一个功能性三元组索引(',' || allowed_types || ',')
才能在大表中获得良好的性能(由于添加了逗号,仅比常规索引稍大)。细节:
或者,使用更复杂的正则表达式,您可以仅使用原始列和三元组索引(allowed_types)
:
SELECT ltrim(regexp_replace('3,4,5,13,14', '((,|^)(4|5))(?=,|$)', '', 'g'), ',');
Run Code Online (Sandbox Code Playgroud)
dbfiddle在这里
但我希望第一个解决方案更快:复杂的正则表达式更昂贵。
UPDATE
UPDATE tbl
SET allowed_types = trim(regexp_replace(',' || allowed_types || ',', ',(4|5)(?=,)', '', 'g'), ',')
WHERE ',' || allowed_types || ',' ~ ',(4|5),'; -- here, plain comma is good
Run Code Online (Sandbox Code Playgroud)
我真正会做什么:
更新到当前版本的 Postgres(第 9.2 页到达 EOL 2017 年 9 月)并可能使用标准化的 1:n 设计。