- ベストアンサー
同一テーブル内での商品価格の比較方法
- 商品と商店の区分ごとに、履歴の最も大きい価格を取得します。
- 商店1を基準に、商品毎に商店2、3の価格差を求めてソートします。
- 希望の出力は、価格差、商品名、商店の順番です。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
商品B-商店3の価格差は 2800 - 2500 なので300になる気がしますが・・・。 それで良いのなら、下記の様なSQLでよろしいかと。 ---------------------------------------- SELECT a.価格 - b.価格 AS 価格差, a.商品ID AS 商品名, a.商店ID AS 商店 FROM 対象テーブル a INNER JOIN 対象テーブル b ON (a.商品ID = b.商品ID AND b.商店ID = '商店1') WHERE a.商店ID <> '商店1' AND a.履歴 = (SELECT MAX(履歴) FROM 対象テーブル c WHERE a.商店ID = c.商店ID AND a.商品ID = c.商品ID) AND b.履歴 = (SELECT MAX(履歴) FROM 対象テーブル d WHERE b.商店ID = d.商店ID AND b.商品ID = d.商品ID) ORDER BY a.価格 - b.価格 DESC; ---------------------------------------- a, b, に対して、それぞれ、商店IDと商品IDが同じものの中で履歴が最大の行だけを抽出しています。 同じ事は EXISTS 句を使っても表現できます。 ---------------------------------------- SELECT a.価格 - b.価格 AS 価格差, a.商品ID AS 商品名, a.商店ID AS 商店 FROM 対象テーブル a INNER JOIN 対象テーブル b ON (a.商品ID = b.商品ID AND b.商店ID = '商店1') WHERE a.商店ID <> '商店1' AND NOT EXISTS (SELECT * FROM 対象テーブル c WHERE a.商店ID = c.商店ID AND a.商品ID = c.商品ID AND a.履歴 < c.履歴) AND NOT EXISTS (SELECT * FROM 対象テーブル d WHERE b.商店ID = d.商店ID AND b.商品ID = d.商品ID AND b.履歴 < d.履歴) ORDER BY a.価格 - b.価格 DESC; ---------------------------------------- こっちは a, b, に対して、それぞれ、商店IDと商品IDが同じでそれより履歴が大きな行が存在しないものだけを抽出しています。 結果として、商店IDと商品IDが同じものの中で履歴が最大の行を取出す事になり、前のSQLと同じ意味になります。 また、サブクエリーで絞り込んでしまい、それを INNER JOIN する方法も有りますね。 ---------------------------------------- SELECT a.価格 - b.価格 AS 価格差, a.商品ID AS 商品名, a.商店ID AS 商店 FROM ( SELECT * FROM 対象テーブル c WHERE 商店ID <> '商店1' AND NOT EXISTS (SELECT * FROM 対象テーブル d WHERE c.商店ID = d.商店ID AND c.商品ID = d.商品ID AND c.履歴 < d.履歴) ) a INNER JOIN ( SELECT * FROM 対象テーブル e WHERE 商店ID = '商店1' AND NOT EXISTS (SELECT * FROM 対象テーブル f WHERE e.商店ID = f.商店ID AND e.商品ID = f.商品ID AND e.履歴 < f.履歴) ) b USING (商品ID) ORDER BY a.価格 - b.価格 DESC; ---------------------------------------- http://gihyo.jp/dev/serial/01/sql_academy2/000901 http://gihyo.jp/dev/serial/01/sql_academy2/000902 http://codezine.jp/article/detail/907
その他の回答 (2)
- Bnbnbnta101
- ベストアンサー率7% (41/516)
create temporary table temp select t1.商品ID ,t1.商店ID ,t1.価格 from テーブル1 as t1 inner join ( select 商品ID,商店ID,max(履歴) as 履歴 from テーブル1 group by 商品ID,商店ID ) as t2 on t1.商品ID = t2.商品ID and t1.商店ID = t2.商店ID and t1.履歴=t2.履歴; ここでセミコロンですね。
お礼
ありがとうございます。 やはり、ここでセミコロンですね。 ただ、後のSELECT文でtempをテーブルではopenできないというエラーが発生します。。。 他に方法があれば教えて頂ければ、お願いします。
補足
tempで開けない理由がわかりました。 ------------ create temporary table temp select t1.商品ID ,t1.商店ID ,t1.価格 from テーブル1 as t1 inner join ( select 商品ID,商店ID,max(履歴) as 履歴 from テーブル1 group by 商品ID,商店ID ) as t2 on t1.商品ID = t2.商品ID and t1.商店ID = t2.商店ID and t1.履歴=t2.履歴; SELECT * FROM temp; -------------------- は実行できました。JOINの中でtempを使うとcann't openとなるようです。 何かわかれば教えてもらえれると助かります。 よろしくお願いします。
- Bnbnbnta101
- ベストアンサー率7% (41/516)
一回履歴で絞り込んだ結果をテンポラリテーブルに入れるのが良いと思います。 create temporary table temp select t1.商品ID ,t1.商店ID ,t1.価格 from テーブル1 as t1 inner join ( select 商品ID,商店ID,max(履歴) as 履歴 from テーブル1 group by 商品ID,商店ID ) as t2 on t1.商品ID = t2.商品ID and t1.商店ID = t2.商店ID and t1.履歴=t2.履歴 select t2.価格-t1.価格 as 価格差 ,t1.商品名 ,t1.商店 from temp as t1 left join ( select 価格,商品 from temp where 商店=商店1 ) as t2 on t1.商品 = t2.商品 where t1.商店<>商店1 ORDER BY t2.価格 - t1.価格 DESC; t1テーブルは基準となるテーブルです。 そこに価格,商品毎にmaxの履歴を絞り込んだt2テーブルを内部結合することによって古い履歴は排除されます。 その結果をテンポラリテーブルに突っ込みます。 ※すみません、mysqlでテンポラリテーブル使ったことないのでこれでいけるでしょうといったところですが。 あとは前回回答したとおりのことをテンポラリテーブルからおこなっているだけです。 やってることは商店1で絞り込んだ結果をサブクエリで結合しているだけです。 説明下手で申し訳ないですがわかりますでしょうか。
お礼
ありがとうございます。鋭意努力中です。 こんなことができるんですね。勉強させて頂きます。 ちなみに、create temporary table tempではエラーが出ないのですが、 このSQL文は;(セミコロン)は最後にのみ付与すれば良いのでしょうか? 構文を見直していますが、 select t2.価格-t1.価格 as 価格差 ,t1.商品名 ,t1.商店 phpMyadminで実行してみていますが、上記の文のところでエラーが発生します。 よろしくお願いします。
お礼
素晴らしいです。 助かりました。これで出力できました。 こういう風にかけば良いんですね。あまりわかってないので 応用が聞きそうにありませんが、理解していきます。 ありがとうございました。