web-dev-qa-db-ja.com

PostgreSQLの文字列内の部分文字列の出現回数をカウントする

PostgreSQLの文字列内の部分文字列の出現回数をカウントするにはどうすればよいですか?


例:

テーブルがあります

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

resultに列oが含まれるサブストリングnameの出現回数を含めるように、クエリを作成します。たとえば、1つの行でnamehello worldである場合、文字列2には2つのresultがあるため、列oにはhello worldが含まれている必要があります。

言い換えれば、入力として受け取るクエリを作成しようとしています。

enter image description here

result列を更新します。

enter image description here


関数 regexp_matches とそのgオプションを認識しています。これは、サブストリングのすべての出現の存在を完全な(g =グローバル)ストリングでスキャンする必要があることを示します)。

例:

SELECT * FROM regexp_matches('hello world', 'o', 'g');

返却値

{o}
{o}

そして

SELECT COUNT(*)  FROM regexp_matches('hello world', 'o', 'g');

返却値

2

しかし、列UPDATEに含まれる部分文字列のサブストリングの数を含むようにresult列を更新するnameクエリを作成する方法がわかりません。

28

一般的な解決策は、次のロジックに基づいています。検索文字列を空の文字列に置き換え、新旧の長さの差を検索文字列の長さで割る

(CHAR_LENGTH(name) - CHAR_LENGTH(REPLACE(name, 'substring', ''))) 
/ CHAR_LENGTH('substring')

したがって:

UPDATE test."user"
SET result = 
    (CHAR_LENGTH(name) - CHAR_LENGTH(REPLACE(name, 'o', ''))) 
    / CHAR_LENGTH('o');
39
dnoeth

これを行うPostgresの方法は、文字列を配列に変換し、配列の長さをカウントします(そして1を引きます)。

select array_length(string_to_array(name, 'o'), 1) - 1

これは、より長い部分文字列でも機能することに注意してください。

したがって:

update test."user"
    set result = array_length(string_to_array(name, 'o'), 1) - 1;
25
Gordon Linoff

文字のカウントを返します。

 SELECT (LENGTH('1.1.1.1') - LENGTH(REPLACE('1.1.1.1','.',''))) AS count
--RETURN COUNT OF CHARACTER '.'
1
Occcurence_Count = LENGTH(REPLACE(string_to_search,string_to_find,'~'))-LENGTH(REPLACE(string_to_search,string_to_find,''))

このソリューションは、特に除数なしで、私が見た多くのものよりも少しきれいです。これを関数にしたり、Select内で使用したりできます。
変数は必要ありません。チルダを置換文字として使用していますが、データセットにない文字はすべて機能します。

0
Robert Bondy

他の方法:

UPDATE test."user" SET result = length(regexp_replace(name, '[^o]', '', 'g'));
0
bnson