下記の目的を満たすSQLの構文を教えてください。


【目的】
客がある時間に買った商品と価格のレコードが入ったテーブルAがあり
(※1人のレコードは複数)、
その中から各客のレコードを一つに絞り込みたい(客1名につき1レコードに)。
絞込みの条件は、一番高い価格が入ったレコードであること。
1人に同価格が存在する場合は、そのうちいずれか。
※同一時間に複数商品をレジに通せるので、1人で同時間に複数レコードあり。


【例】 
(ID)   (日付)    (商品) (価格)
ggggg 2000/1/1/0:00  商品A ¥500
ggggg 2000/1/1/0:00  商品B ¥300
ggggg 2000/1/1/0:00  商品C ¥200
eeeee 2002/3/1/0:00  商品A ¥300
eeeee 2002/3/1/0:00  商品B ¥400
eeeee 2002/3/1/0:00  商品C ¥400

★この場合
ggggg 2000/1/1/0:00  商品A ¥500
eeeee 2002/3/1/0:00  商品B ¥400
または、
ggggg 2000/1/1/0:00  商品A ¥500
eeeee 2002/3/1/0:00  商品C ¥400
が結果として選択されるように。


何日か考えたのですが答えが出ず、お知恵をお借りしたいです。
よろしくお願いします。

回答の条件
  • 1人50回まで
  • 登録:
  • 終了:2012/06/13 16:17:10

ベストアンサー

id:windofjuly No.2

回答回数2625ベストアンサー獲得回数1149

1件ずつ抽出したいならば、
レコードをユニークにする必要がありますので、
例えば下記のような具合に番号を振ります。
(テーブルにオートナンバー型フィールドを追加するだけならば、
 フォームやレポートなどの改造をしなくて済むので楽ですよ。)

ID日付商品価格通し番号
ggggg2000/01/01商品A5001
ggggg2000/01/01商品B3002
ggggg2000/01/01商品C2003
eeeee2000/01/03商品A3004
eeeee2000/01/03商品B4005
eeeee2000/01/03商品C4006
eeeee2000/01/03商品D4007

クエリの例

SELECT ID, 日付, 商品, 価格
FROM テーブル AS t1
WHERE 通し番号 = (SELECT TOP 1 通し番号 FROM テーブル AS t2 WHERE t2.ID = t1.ID ORDER BY 価格 DESC, 通し番号);
他9件のコメントを見る
id:windofjuly

丸囲み数字はメールのほうでは?になるので、
使わないほうがいいみたいです。

さて、
動作を言葉にすると次のような具合です。
1.FROM に示されたテーブルから、
2.WHERE の条件にあうレコードだけを、
3.ORDER BY の順で並び変えて、
4.SELECT に示されたもの(通し番号)を出力しろ
  ただし、TOP 1(1番目だけ)でいい

今回の場合は以上のような流れになってますが、
ちょっと変えただけで流れが大きく変わる場合もあります。

このような動作の詳細についてはAccess関連の本にはほとんど載ってません。
(Accessの操作方法までで終わってますよね)

SQL入門系とかデータベース概論系の本を読んでSQLの基礎を学び、
さらに、Access独特のクセを覚えて対応してくという流れになりますので、
あせらず、ゆっくり時間をかけて学んでください。

2012/06/13 15:59:30
id:nao14

ご回答ありがとうございます。

SQLを基礎から学びつつ実践していきたいと思います!!!

2012/06/13 16:16:59

その他の回答1件)

id:JULY No.1

回答回数966ベストアンサー獲得回数247

4つのフィールドが id, date, item, price という名前で、テーブル名が table1 だったとして、

select id, date, item, max(price) from table1 group by id
他2件のコメントを見る
id:nao14

group byとselect句の関係を勘違いしていたようですみません。
ただ、頂いた構文のままだと実行できず、
group by以下にすべてのカラムを入れると実行できるので、
てっきりそういう仕組みかと。。。
他の原因があるようですね。試行錯誤してみます。

2012/06/12 17:12:03
id:windofjuly

本題とは関係ないことですが、双方話が食い違っているので横槍失礼します。

>select id, date, item, max(price) from table1 group by id
回答欄のような表記のdateやitemに対して、
MySQLは適当に処理してくれるのですが、
他のデータベースでは曖昧さ回避のためエラーになります。
すなわちJULYさんの回答ならびに返答はMySQLにおいてのみ有効となるものです。

今回の件はAccessであるとコメントに記載されているので、
nao14さんが認識しておられたSELECTとGROUP BYの関係は間違いではありません。

なお、私の回答は別の回答欄に書くこととしますので、そちらを参照してください。

2012/06/12 21:55:52
id:windofjuly No.2

回答回数2625ベストアンサー獲得回数1149ここでベストアンサー

1件ずつ抽出したいならば、
レコードをユニークにする必要がありますので、
例えば下記のような具合に番号を振ります。
(テーブルにオートナンバー型フィールドを追加するだけならば、
 フォームやレポートなどの改造をしなくて済むので楽ですよ。)

ID日付商品価格通し番号
ggggg2000/01/01商品A5001
ggggg2000/01/01商品B3002
ggggg2000/01/01商品C2003
eeeee2000/01/03商品A3004
eeeee2000/01/03商品B4005
eeeee2000/01/03商品C4006
eeeee2000/01/03商品D4007

クエリの例

SELECT ID, 日付, 商品, 価格
FROM テーブル AS t1
WHERE 通し番号 = (SELECT TOP 1 通し番号 FROM テーブル AS t2 WHERE t2.ID = t1.ID ORDER BY 価格 DESC, 通し番号);
他9件のコメントを見る
id:windofjuly

丸囲み数字はメールのほうでは?になるので、
使わないほうがいいみたいです。

さて、
動作を言葉にすると次のような具合です。
1.FROM に示されたテーブルから、
2.WHERE の条件にあうレコードだけを、
3.ORDER BY の順で並び変えて、
4.SELECT に示されたもの(通し番号)を出力しろ
  ただし、TOP 1(1番目だけ)でいい

今回の場合は以上のような流れになってますが、
ちょっと変えただけで流れが大きく変わる場合もあります。

このような動作の詳細についてはAccess関連の本にはほとんど載ってません。
(Accessの操作方法までで終わってますよね)

SQL入門系とかデータベース概論系の本を読んでSQLの基礎を学び、
さらに、Access独特のクセを覚えて対応してくという流れになりますので、
あせらず、ゆっくり時間をかけて学んでください。

2012/06/13 15:59:30
id:nao14

ご回答ありがとうございます。

SQLを基礎から学びつつ実践していきたいと思います!!!

2012/06/13 16:16:59

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません