文字列が与えられます:
「PostgreSQLは気の利いたものだと思います」
その文字列内で見つかった個々の単語を操作したいと思います。基本的に、Wordの詳細を取得できる別のものがあり、その文字列のネストされていない配列をこの辞書に結合したいと考えています。
これまでのところ:
select Word, meaning, partofspeech
from unnest(string_to_array('I think that PostgreSQL is nifty',' ')) as Word
from table t
join dictionary d
on t.Word = d.wordname;
これにより、私が望んでいたことの基本が実現しますが、元のWordの順序は保持されません。
関連する質問:
要素番号を持つPostgreSQL unnest()
WITH ORDINALITY
_新しい機能は、このクラスの問題を単純化します。上記のクエリは次のようになります。
_SELECT *
FROM regexp_split_to_table('I think Postgres is nifty', ' ') WITH ORDINALITY x(Word, rn);
_
または、テーブルに適用されます:
_SELECT *
FROM tbl t, regexp_split_to_table(t.my_column, ' ') WITH ORDINALITY x(Word, rn);
_
詳細:
暗黙のLATERAL
結合について:
ウィンドウ関数 row_number()
を適用して、要素の順序を記憶できます。ただし、通常のrow_number() OVER (ORDER BY col)
では、文字列の元の位置ではなく、ソート順に従って数値を取得します。
_ORDER BY
_を省略して、「現状のまま」の位置を取得できます。
_SELECT *, row_number() OVER () AS rn
FROM regexp_split_to_table('I think Postgres is nifty', ' ') AS x(Word);
_
長い文字列を使用すると、regexp_split_to_table()
のパフォーマンスが低下します。 unnest(string_to_array(...))
より適切にスケーリングされます:
_SELECT *, row_number() OVER () AS rn
FROM unnest(string_to_array('I think Postgres is nifty', ' ')) AS x(Word);
_
ただし、これは正常に機能し、単純なクエリで壊れることはありませんでしたが、Postgresは明示的な_ORDER BY
_がない場合、行の順序について何もアサートしません。
guarantee元の文字列の要素の序数には、 generate_subscript()
を使用します(@deszoによるコメントで改善):
_SELECT arr[rn] AS Word, rn
FROM (
SELECT *, generate_subscripts(arr, 1) AS rn
FROM string_to_array('I think Postgres is nifty', ' ') AS x(arr)
) y;
_
_PARTITION BY id
_をOVER
句に追加...
デモ表:
_CREATE TEMP TABLE strings(string text);
INSERT INTO strings VALUES
('I think Postgres is nifty')
,('And it keeps getting better');
_
主キーのアドホック代替としてctid
を使用しています。 1つ(またはの一意の列)がある場合は、代わりにそれを使用します。
_SELECT *, row_number() OVER (PARTITION BY ctid) AS rn
FROM (
SELECT ctid, unnest(string_to_array(string, ' ')) AS Word
FROM strings
) x;
_
これは明確なIDなしで機能します:
_SELECT arr[rn] AS Word, rn
FROM (
SELECT *, generate_subscripts(arr, 1) AS rn
FROM (
SELECT string_to_array(string, ' ') AS arr
FROM strings
) x
) y;
_
_SELECT z.arr, z.rn, z.Word, d.meaning -- , partofspeech -- ?
FROM (
SELECT *, arr[rn] AS Word
FROM (
SELECT *, generate_subscripts(arr, 1) AS rn
FROM (
SELECT string_to_array(string, ' ') AS arr
FROM strings
) x
) y
) z
JOIN dictionary d ON d.wordname = z.Word
ORDER BY z.arr, z.rn;
_