文字列が含まれている場合、Postgresql SELECT


105

だから私は私のPostgresqlにあります:

TAG_TABLE
==========================
id            tag_name       
--------------------------
1             aaa
2             bbb
3             ccc

私の問題を簡単にするために、文字列 "aaaaaaaa"に 'tag_name'が含まれている場合に、TAG_TABLEからSELECT 'id'を実行します。したがって、理想的には、タグ名「aaa」のIDである「1」のみを返す必要があります。

これは私がこれまでやっていることです:

SELECT id FROM TAG_TABLE WHERE 'aaaaaaaaaaa' LIKE '%tag_name%'

しかし、明らかに、これは機能しません。postgresは、 '%tag_name%'は、その列の下の実際のデータ値ではなく、部分文字列 'tag_name'を含むパターンを意味すると考えているためです。

tag_nameをパターンに渡すにはどうすればよいですか?

回答:


131

引用符の外で 'tag_name'を使用する必要があります。その後、レコードのフィールドとして解釈されます。'||'を使用して連結 文字通りのパーセント記号で:

SELECT id FROM TAG_TABLE WHERE 'aaaaaaaa' LIKE '%' || tag_name || '%';

5
tag_nameが"; drop table TAG_TABLE; --"何であるか
Denis de Bernardy 2014

24
@Denis:何も起こりません。WHERE句はと評価されるため、行は取得されませんFALSE。ステートメントは動的ではなく、値のみが連結され、SQLインジェクションの可能性はありません。
Erwin Brandstetter 2014

1
aaaaとtag_nameの順序を逆にしないでください。私はあなたがどこにカラム名を置くべきであることを意味します
user151496

@ user151496いいえ、パターンはLIKEキーワードの右側に配置する必要があるためです。
jpmc26 2016年

4
LIKEパターンで変数を使用すると、それらの変数にアンダースコア(_)またはパーセント文字(%)が含まれている場合、意図しない結果になる可能性があることに注意してください。たとえば、次の関数CREATE OR REPLACE FUNCTION quote_for_like(text) RETURNS text LANGUAGE SQL IMMUTABLE AS $$ SELECT regexp_replace($1, '([\%_])', '\\\1', 'g'); $$;を使用して、これらの文字をエスケープする必要がある場合があります(Freenodeの#postgresql IRCチャネルからユーザーMatheusOlから)。
Martin von Wittich、2016

46

私は個人的には〜演算子のより単純な構文を好みます。

SELECT id FROM TAG_TABLE WHERE 'aaaaaaaa' ~ tag_name;

LIKEと〜の違いをPostgresで読み、違いを理解する価値があります。`


2
これtag_nameは、が適切な正規表現である場合にのみ機能します。かなり危険です。
Jakub Fedyczak 2017

@JakubFedyczak ***=は、postgresql.org / docs / current / static / functions-matching.html で言及されている、使用できるリテラルtag_nameと一致します。しかし、私はstrpos/ positionソリューションに比べて非常に遅いことがわかりました。
phunehehe

27

部分文字列を検索するための適切な方法で使用することpositionの代わりに機能をlikeエスケープ必要とする、表現%_および(エスケープ文字\はデフォルトで):

SELECT id FROM TAG_TABLE WHERE position(tag_name in 'aaaaaaaaaaa')>0;

これはこれを行う正しい方法です。ハックな正規表現アプローチを使用するべきではありません。
khol

LIKEそして、ILIKE使用できるginインデックスを。positionできません。
Eugene Pakhomov

14

(argsの逆順)と'aaaaaaaa' LIKE '%' || tag_name || '%'があるソリューションに加えて。positionstrpos

SELECT id FROM TAG_TABLE WHERE strpos('aaaaaaaa', tag_name) > 0

より効率的であるものをほか(LIKEが少なく効率的に見えますが、インデックスは、物事を変更する場合があります)、LIKEに非常にマイナーな問題があります。もちろん、タグ名を含めるべきではありません%し、特に_(単一文字のワイルドカード)、偽陽性を与えないように。


2
strposはいつも私のために0を返したように私は、位置とstrposを交換しなければならなかった
JCF

-2
SELECT id FROM TAG_TABLE WHERE 'aaaaaaaa' LIKE '%' || "tag_name" || '%';

tag_name 引用符で囲む必要があります。そうでない場合、tag_nameが存在しないためエラーになります


2
これは、受け入れられた回答の正反対です。列である必要がある一方で、文字列として連結しています...
Suraj Rao
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.