アプリ版:「スタンプのみでお礼する」機能のリリースについて

PostgreSQLで複数の条件での絞り込み検索をしたいのです。

テーブルには
発売日、商品名、入荷日
があります。
例えば
発売日が2007年5月1日から5月5日で、商品名に「○○」もしくは「××」もしくは「△△」が含まれており、入荷日が一番新しいもの
という条件で検索したいのです。

発売日だけの絞込みならBetweenですし、商品名だけならor、入荷日の最新だったらmaxを使えば個別には検索できるのですが、これをまとめて一行でやるにはどうしたらよいのかわかりません。
それぞれでandでつなげてみましたが、orの条件がうまく反映されず、一個目の○○だけが検索に引っかかってる状態です。
××や△△もひっかかるようにするにはどう記述したらよいのでしょうか。

A 回答 (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 '%△△%')
    • good
    • 1

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'
    • good
    • 2

こんにちは。


あまり綺麗なSQL文になりませんでしたが、ご参考までに。

【テーブル定義】
create table t_stock (
stock_nointeger not null, -- 仕入番号
item_namecharacter(100) not null, -- 商品名
item_countinteger not null default 0, -- 商品数
sale_datedate, -- 発売日
arrival_datedate, -- 入荷日
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
    • good
    • 1

バージョンにもよりますが、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
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
説明不足ですみません。

まず、○○を「含む」なのでlikeでなくてはならないのですが、それでもinを使うことは可能でしょうか。

次に入荷日が最新とはいえ、○○も△△も××も同じ日に入荷する可能性があります。
ゆえにlimit 1で一行だけではなく入荷日が最新であれば○○も××も結果に出したいのです。
なのでlimitではなくmaxで最新の全部という引っ張り方が必要かなと思いました。

お礼日時:2007/05/06 16:03

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!