如何在 PostgreSQL 9.2 中从带有整数 CSV 的 col 中删除元素?

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)

如何从中删除45allowed_types其中以逗号分隔的 varchar 列表?

删除后,结果应该是allowed_types = 3,13,14

该表上有许多记录,每个记录allowed_types可以包含不同的数字,用逗号分隔。

我考虑过string_to_array()and array_remove(),但array_remove()还没有在 9.2 版中。

Erw*_*ter 5

正则表达式的概念证明:

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 设计。

  • 我有点困惑,但是`SELECT trim(regexp_replace(',' || '3,4,5,13,​​14' || ',', ',(4|5),', ',', ' g'), ',')` 返回 `3,5,13,​​14`,而不是 `3,13,14`:[dbfiddle](http://dbfiddle.uk/?rdbms=postgres_9.4&fiddle=bbaede8e48ef893868bcc31c8c3351ac) (2认同)