PostgreSQLの文字列内の部分文字列の出現回数をカウントするにはどうすればよいですか?
例:
テーブルがあります
CREATE TABLE test."user"
(
uid integer NOT NULL,
name text,
result integer,
CONSTRAINT pkey PRIMARY KEY (uid)
)
result
に列o
が含まれるサブストリングname
の出現回数を含めるように、クエリを作成します。たとえば、1つの行でname
がhello world
である場合、文字列2
には2つのresult
があるため、列o
にはhello world
が含まれている必要があります。
言い換えれば、入力として受け取るクエリを作成しようとしています。
result
列を更新します。
関数 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
クエリを作成する方法がわかりません。
一般的な解決策は、次のロジックに基づいています。検索文字列を空の文字列に置き換え、新旧の長さの差を検索文字列の長さで割る
(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');
これを行う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;
文字のカウントを返します。
SELECT (LENGTH('1.1.1.1') - LENGTH(REPLACE('1.1.1.1','.',''))) AS count
--RETURN COUNT OF CHARACTER '.'
Occcurence_Count = LENGTH(REPLACE(string_to_search,string_to_find,'~'))-LENGTH(REPLACE(string_to_search,string_to_find,''))
このソリューションは、特に除数なしで、私が見た多くのものよりも少しきれいです。これを関数にしたり、Select内で使用したりできます。
変数は必要ありません。チルダを置換文字として使用していますが、データセットにない文字はすべて機能します。
他の方法:
UPDATE test."user" SET result = length(regexp_replace(name, '[^o]', '', 'g'));