-3

flag_acumu次のような値を持つ PostgreSQL のテーブルに列があります。

'SSNSSNNNNNNNNNNNNNNNNNNNNNNNNNNNNSNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN'

すべての位置を「S」で表示する必要があります。このコードでは、最初のそのような位置のみを取得しますが、後の位置は取得しません。

SELECT codn_conce, flag_acumu, position('S' IN flag_acumu) AS the_pos 
FROM dh12 
WHERE position('S' IN flag_acumu) != 0 
ORDER BY the_pos ASC;

それらをすべて取得するにはどうすればよいですか?

4

3 に答える 3

2

Postgres 9.4以降では、以下unnest()と組み合わせて便利に使用できWITH ORDINALITYます。

SELECT *
FROM   dh12 d
JOIN   unnest(string_to_array(d.flag_acumu, NULL))
          WITH ORDINALITY u(elem, the_pos) ON u.elem = 'S'
WHERE  d.flag_acumu LIKE '%S%'  -- optional, see below
ORDER  BY d.codn_conce, u.the_pos;

これにより、一致ごとに 1 行が返されます。 WHERE d.flag_acumu LIKE '%S%'一致しないソース行をすばやく削除するためのオプションです。そのような行が数行以上ある場合に支払われます。

古いバージョンの詳細な説明と代替手段:

于 2015-12-28T15:40:37.783 に答える
2

適切に答えることができるポイントまでニーズを指定していないので、部分文字列の出現位置のリストが必要であると仮定します (1 文字以上になる場合があります)。

これを使用してそれを行う関数は次のとおりです。

  • FOR .. LOOP制御構造、
  • 機能substr(text, int, int)

CREATE OR REPLACE FUNCTION get_all_positions_of_substring(text, text)
RETURNS text
STABLE
STRICT
LANGUAGE plpgsql
AS $$
DECLARE
  output_text TEXT := '';
BEGIN

FOR i IN 1..length($1)
LOOP
  IF substr($1, i, length($2)) = $2 THEN
    output_text := CONCAT(output_text, ';', i);
  END IF;
END LOOP;

-- Remove first semicolon
output_text := substr(output_text, 2, length(output_text));

RETURN output_text;
END;
$$;

呼び出しと出力の例

postgres=# select * from get_all_positions_of_substring('soklesocmxsoso','so');
 get_all_positions_of_substring
--------------------------------
 1;6;11;13
于 2015-12-28T15:40:02.503 に答える
0

これも機能します。そして、少し速いと思います。

create or replace function findAllposition(_pat varchar, _tar varchar) 
returns int[] as
$body$
declare _poslist int[]; _pos int;
begin

_pos := position(_pat in _tar);
while (_pos>0)
loop

    if array_length(_poslist,1) is null then
        _poslist := _poslist || (_pos);
    else
        _poslist := _poslist || (_pos + _poslist[array_length(_poslist,1)] + 1);
    end if;

    _tar := substr(_tar, _pos + 1, length(_tar));
    _pos := position(_pat in _tar);

end loop;
return _poslist;

end;
$body$
language plpgsql;

int 配列である位置リストを返します。

{position1, position2, position3, etc.}
于 2016-01-23T14:42:10.380 に答える