2

これがテーブル構造です

table1
pk int, email character varying(100)[]

data
1, {'mr_a@gmail.com', 'mr_b@yahoo.com', 'mr_c@postgre.com'}

私が達成しようとしているのは、レコードから「Gmail」を見つけることです

query
select * from table1 where any(email) ilike '%gmail%';

ただし、any()は左側にしか配置できず、unnest()はパフォーマンスを低下させる可能性があります。誰かが何か考えがありますか?

編集

実際、最初に投稿したときは少し混乱します。any(array [])を介して達成しようとします。

これが私の実際の構造です

pk int, 
code1 character varying(100), 
code2 character varying(100), 
code3 character varying(100), ...

私の最初のアプローチは

select * from tabl1 where code1 ilike '%code%' or code2 ilike '%code%' or...

それから私は試してみます

select * from table1 where any(array[code1, code2, ...]) ilike '%code%'

動作していません。

4

2 に答える 2

5

ILIKE「後方」を実装する演算子を作成します。例:

CREATE FUNCTION backward_texticlike(text, text) RETURNS booleans
    STRICT IMMUTABLE LANGUAGE SQL
    AS $$ SELECT texticlike($2, $1) $$;

CREATE OPERATOR !!!~~* (
    PROCEDURE = backward_texticlike,
    LEFTARG = text,
    RIGHTARG = text,
    COMMUTATOR = ~~*
);

ILIKE(内部的には operator に対応することに注意して~~*ください。逆の場合は独自の名前を選択してください。)

その後、実行できます

SELECT * FROM table1 WHERE '%code%' !!!~~* ANY(ARRAY[code1, code2, ...]);
于 2011-03-26T20:23:34.287 に答える
2

電子メール アドレスを正規化されたテーブル構造に格納します。そうすれば、 の費用を回避し、unnest「適切な」データベース設計を行い、インデックス作成を最大限に活用できます。全文形式のクエリを実行する場合は、メール アドレスをテーブルに保存してから、tsvector データ型を使用して、全文クエリを実行し、インデックスを使用できるようにする必要があります。ILIKE '%whatever%'プランナーはクエリを利用できないため、テーブル全体のスキャンが発生します。現在のデザインと十分な数のレコードがあれunnestば、心配はほとんどありません。

更新質問が更新されたとしても、正規化されたコード テーブルを使用すると、頭痛が最小限に抑えられ、最適なスキャンが得られます。番号付きの列を作成していることに気付いた場合はいつでも、正規化する必要がある可能性があることを示しています。そうは言っても、計算されたテキスト列を作成して、検索語列として使用できます。あなたの場合search_words、トリガーによる挿入および更新時に入力される列を作成できます。次に、 を作成しtsvectorて、search_words

于 2011-03-21T12:11:01.560 に答える