- ベストアンサー
複数の条件での絞り込み検索の仕方
PostgreSQLで複数の条件での絞り込み検索をしたいのです。 テーブルには 発売日、商品名、入荷日 があります。 例えば 発売日が2007年5月1日から5月5日で、商品名に「○○」もしくは「××」もしくは「△△」が含まれており、入荷日が一番新しいもの という条件で検索したいのです。 発売日だけの絞込みならBetweenですし、商品名だけならor、入荷日の最新だったらmaxを使えば個別には検索できるのですが、これをまとめて一行でやるにはどうしたらよいのかわかりません。 それぞれでandでつなげてみましたが、orの条件がうまく反映されず、一個目の○○だけが検索に引っかかってる状態です。 ××や△△もひっかかるようにするにはどう記述したらよいのでしょうか。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
データ件数がどのくらいあるのかは分かりませんが、ユニークなキーもなく、likeの任意一致をorでつなぐという方法は、性能を出せませんよ? select * from t1 where 入荷日 in( select max(入荷日) from t1 where 発売日 between '2007-05-01' and '2007-05-05' and (商品名 like '%○○%' or 商品名 like '%××%' or 商品名 like '%△△%') ) and 発売日 between '2007-05-01' and '2007-05-05' and (商品名 like '%○○%' or 商品名 like '%××%' or 商品名 like '%△△%')
その他の回答 (3)
- world99
- ベストアンサー率64% (20/31)
world99です。 chukenkenkouさんのSQL文の方が綺麗ですね。 そちらをご参考下さい。おかげさまで、私もいい勉強になりました。 ちなみに、私のサンプルにあったSQL文は以下のようになります。 SELECT t1.* FROM t_stock t1 WHERE t1.arrival_date IN( SELECT MAX(arrival_date) FROM t_stock WHERE (item_name like '%○%' OR item_name like '%×%' OR item_name like '%△%') AND sale_date >= '2007-05-01' AND sale_date <= '2007-05-05' ) AND (t1.item_name like '%○%' OR t1.item_name like '%×%' OR t1.item_name like '%△%') AND sale_date >= '2007-05-01' AND sale_date <= '2007-05-05'
- world99
- ベストアンサー率64% (20/31)
こんにちは。 あまり綺麗なSQL文になりませんでしたが、ご参考までに。 【テーブル定義】 create table t_stock ( stock_no integer not null, -- 仕入番号 item_name character(100) not null, -- 商品名 item_count integer not null default 0, -- 商品数 sale_date date, -- 発売日 arrival_date date, -- 入荷日 primary key(stock_no) ); 【データ】○○などは、短くして1字にして登録しています。 insert into t_stock(stock_no, item_name, item_count, sale_date, arrival_date) values(1, '○あめ', 10, '2007-04-30', '2007-05-01'); insert into t_stock(stock_no, item_name, item_count, sale_date, arrival_date) values(2, '×あめ', 10, '2007-05-01', '2007-05-01'); insert into t_stock(stock_no, item_name, item_count, sale_date, arrival_date) values(3, '△あめ', 10, '2007-05-01', '2007-05-01'); insert into t_stock(stock_no, item_name, item_count, sale_date, arrival_date) values(4, '□あめ', 10, '2007-05-04', '2007-05-05'); insert into t_stock(stock_no, item_name, item_count, sale_date, arrival_date) values(5, '×あめ', 10, '2007-05-04', '2007-05-05'); insert into t_stock(stock_no, item_name, item_count, sale_date, arrival_date) values(6, '△あめ', 10, '2007-05-05', '2007-05-05'); insert into t_stock(stock_no, item_name, item_count, sale_date, arrival_date) values(7, '○あめ', 20, '2007-05-06', '2007-05-06'); 【データ取得SQL文】 SELECT t1.* FROM t_stock t1 INNER JOIN ( SELECT max(arrival_date) AS arrival_date FROM t_stock WHERE (item_name like '%○%' OR item_name like '%×%' OR item_name like '%△%') AND sale_date >= '2007-05-01' AND sale_date <= '2007-05-05' ) t2 ON (t1.arrival_date = t2.arrival_date) WHERE (t1.item_name like '%○%' OR t1.item_name like '%×%' OR t1.item_name like '%△%') ORDER BY stock_no
- chukenkenkou
- ベストアンサー率43% (833/1926)
バージョンにもよりますが、orを使うよりinを使った方が、性能が出る場合があります。 (1)inを使う例 select * from t1 where 発売日 between '2007-05-01' and '2007-05-05' and 商品名 in('○○','××','△△') order by 入荷日 desc limit 1 (2)orを使う例 select * from t1 where 発売日 between '2007-05-01' and '2007-05-05' and (商品名='○○' or 商品名='××' or 商品名='△△') order by 入荷日 desc limit 1
お礼
ご回答ありがとうございます。 説明不足ですみません。 まず、○○を「含む」なのでlikeでなくてはならないのですが、それでもinを使うことは可能でしょうか。 次に入荷日が最新とはいえ、○○も△△も××も同じ日に入荷する可能性があります。 ゆえにlimit 1で一行だけではなく入荷日が最新であれば○○も××も結果に出したいのです。 なのでlimitではなくmaxで最新の全部という引っ張り方が必要かなと思いました。