计算PostgreSQL中字符串中子字符串的出现次数

Fra*_*urt 32 sql string postgresql

如何计算PostgreSQL中字符串中子字符串的出现次数?


例:

我有一张桌子

CREATE TABLE test."user"
(
  uid integer NOT NULL,
  name text,
  result integer,
  CONSTRAINT pkey PRIMARY KEY (uid)
)
Run Code Online (Sandbox Code Playgroud)

我想编写一个查询,以便result包含列o列中name包含的子字符串的出现次数.例如,如果在一行中,namehello worldresult应该包含2,因为o字符串中有两个hello world.

换句话说,我正在尝试编写一个可以作为输入的查询:

在此输入图像描述

并更新result列:

在此输入图像描述


我知道函数regexp_matches及其g选项,它指示g需要扫描完整(=全局)字符串是否存在所有出现的子字符串).

例:

SELECT * FROM regexp_matches('hello world', 'o', 'g');
Run Code Online (Sandbox Code Playgroud)

回报

{o}
{o}
Run Code Online (Sandbox Code Playgroud)

SELECT COUNT(*)  FROM regexp_matches('hello world', 'o', 'g');
Run Code Online (Sandbox Code Playgroud)

回报

2
Run Code Online (Sandbox Code Playgroud)

但我没有看到如何编写一个UPDATE查询来更新result列,使其包含列name包含的子串的出现次数.

dno*_*eth 42

一个常见的解决方案是基于这样的逻辑:用空字符串替换搜索字符串,并将新旧长度之间的差异除以搜索字符串的长度

(CHAR_LENGTH(name) - CHAR_LENGTH(REPLACE(name, 'substring', ''))) 
/ CHAR_LENGTH('substring')
Run Code Online (Sandbox Code Playgroud)

因此:

UPDATE test."user"
SET result = 
    (CHAR_LENGTH(name) - CHAR_LENGTH(REPLACE(name, 'o', ''))) 
    / CHAR_LENGTH('o');
Run Code Online (Sandbox Code Playgroud)

  • 这是一个可靠的答案,而且是正确的。您可能对我的文章感兴趣[执行此操作的所有方法](http://dba.stackexchange.com/a/166763/2639) (2认同)

Gor*_*off 27

Postgres的做法是将字符串转换为数组并计算数组的长度(然后减去1):

select array_length(string_to_array(name, 'o'), 1) - 1
Run Code Online (Sandbox Code Playgroud)

请注意,这也适用于较长的子串.

因此:

update test."user"
    set result = array_length(string_to_array(name, 'o'), 1) - 1;
Run Code Online (Sandbox Code Playgroud)

  • @EvanCarroll不幸的是,dnoeth的答案不适用于正则表达式匹配,因为你可能不知道匹配的长度.这个答案适用于正则表达式匹配和原始字符串匹配.我认为我们称之为_better_的解决方案适合你想做的一切:) (3认同)
  • 如果有人需要regexp,那么使用"regexp_split_to_array"而不是"string_to_array"的解决方案也可以. (2认同)
  • @用户2297550。。。大多数数据库本身不支持数组。 (2认同)

小智 9

返回字符数,

 SELECT (LENGTH('1.1.1.1') - LENGTH(REPLACE('1.1.1.1','.',''))) AS count
--RETURN COUNT OF CHARACTER '.'
Run Code Online (Sandbox Code Playgroud)


小智 7

另一种方式:

UPDATE test."user" SET result = length(regexp_replace(name, '[^o]', '', 'g'));
Run Code Online (Sandbox Code Playgroud)


小智 7

Occcurence_Count = LENGTH(REPLACE(string_to_search,string_to_find,'~'))-LENGTH(REPLACE(string_to_search,string_to_find,''))
Run Code Online (Sandbox Code Playgroud)

这个解决方案比我见过的许多解决方案要干净一些,尤其是没有除数的情况。您可以将其转换为函数或在 Select 中使用。
不需要变量。我使用波形符作为替换字符,但数据集中不存在的任何字符都可以使用。