[pgsql-jp: 29233] Re: 任意の項目に対して、空白で区切ってAND 検索をするには

Mashiki mashiki @ yanah.com
2003年 2月 26日 (水) 02:55:00 JST


パズル大好きモードのMashikiです。


>Select文を使って、任意の一つの項目にたいして検索を行う場合、
>
>select * from テーブル名 where 項目名 like '検索したい文字列';
>
>として検索結果を出力させています。ここまではうまく出力しております。
>
>そこで、項目に対して、AND検索をしたいのですが、希望するのは空白を認識して
>AND検索を行うものです。


結論は出てしまっているようですが、このSQLパズルを考えてみました。
実用になるかどうかはおいておいて.....くださいね。

select * from テーブル名 where 項目名 like '検索したい文字列';

を以下のように

select * from テーブル名
where repeat(
		項目名||' ', キーワード個数
      )
       like
      replace(' 空白で区切った検索したい文字列 ',' ','%')
;

と書き換えると検索可能になります。項目名をリピートするのは、
キーワードを実際の並びと逆順に指定されたときのためです。

キーワード個数はプログラミング言語で「(区切り文字=空白の個数)+1」
をセットできればいいのですが、SQLにこだわるなら

 1+len('検索したい文字列')-len(replace('検索したい文字列',' ',''))

で、キーワードの個数をカウントできます。

# strCount('検索したい文字列')+1 とかければキレイなのですが...
# なんかやりようないですかねえ?

で、以下は7.3以上で動きます。


/* 確認用SQL */
create table m_like (id int4 , txt text);
insert into m_like values (1,'AAA BBB CCC DDD EEE FFF GGG HHH');
insert into m_like values (2,'CCC DDD EEE FFF GGG HHH III JJJ');
insert into m_like values (3,'III JJJ KKK LLL MMM NNN OOO PPP');
insert into m_like values (4,'AAA XXX YYY ZZZ CCC DDD EEE BBB');

/* 実際の検索 */
select * from m_like
 where repeat(txt||' ',
             1 + length('BBB DDD')
             - length(replace('BBB DDD',' ',''))
      )
      like
      replace(' BBB DDD ',' ','%%')
;

/* 片付け */
drop table m_like;


と、思ったら7.2.3ユーザーの方ですね。
「キーワード個数」はあらかじめ最大を決めておけば、

/* 実際の検索(機能制限版) */
select * from m_like
 where repeat(txt||' ',9)
      like
      translate(' BBB DDD ',' ','%%')
;

で、検索可能です。




pgsql-jp メーリングリストの案内