次のようなSQLが知りたいです。細かいですがお願いします。
「使用テーブル」 Orderテーブル、Order明細テーブル、価格テーブル
「各表の列」 Orderテーブル [OrderNo] 売り先
Order明細テーブル [OrderNo] [商品名] 個数
価格テーブル [商品名][売り先] 価格
[ ]が主キーです。
つまり価格は売り先によって値段が違います。
3つのテーブルを結合してSELECTしOrderNo,商品名,価格を出したいです。
条件は各OrderNoについて個数が一番多い商品名とその価格を表示。
もし個数が同じなら、さらに商品名の文字列順序の早い方で1つ選択。
OrderテーブルにはOrderNoがあるが明細がない場合は、OrderNo以外ブランク。
価格テーブルに商品の価格が登録されてなかったら、価格部分はブランク。
次がややこしいです。
価格テーブルである商品について、すべての売り先に対して
同じ価格なら売り先に'*****’が入ります。
つまり、価格テーブルで1つの商品について個別の売り先で値段が
設定されてなくても、'*****'ならその商品の価格がわかることになります。
'*****'も個別の売り先も登録されていなかったら、その商品の値段がわかりません。
もし、価格テーブルに同じ商品について売り先が
'*****'と個別の売り先名の両方で登録されていたら個別の方の価格を選択。
以上です。
Orderテーブルに100件あれば、上のようにすれば100件でると思います。
よろしくお願いします。
No.5ベストアンサー
- 回答日時:
分析関数が使える環境なら・・
--価格管理が矛盾しないなら
select A.OrderNo,B.商品名,C.価格
from Order A
left join (select X.*,row_number() over(partition by OrderNo order by 個数 desc,商品名) R from Order明細 X) B
ON (A.OrderNo=B.OrderNo and R=1)
left join 価格 C ON((C.商品名,C.売り先) in ((B.商品名,A.売り先),(B.商品名,'*****')))
--価格管理が矛盾するなら
select A.OrderNo,B.商品名,nvl(D.価格,C.価格) as 価格
from Order A
left join (select X.*,row_number() over(partition by OrderNo order by 個数 desc,商品名) R from Order明細 X) B
ON (A.OrderNo=B.OrderNo and R=1)
left join 価格 C ON(C.商品名=B.商品名 and C.売り先='*****')
left join 価格 D ON(D.商品名=B.商品名 and D.売り先=A.売り先)
という感じで書けると思いますよ。(未検証、目視確認のみのSQLです)
No.4
- 回答日時:
>このSQLの場合、もし価格テーブルに求める商品名がなかったらどうなるのでしょうか?
>ブランクになると思うんですが自信がなくて。
ビュー:集計結果でLEFT JOINで結合しているので、
ブランク(NULL)になります。
(Accessで動作確認しました)
>'*****'と個別価格の両方の行が絶対ないと仮定した上だとどうなるのでしょうか?
>もっと簡単になりますか?
残念ながら、簡単にはなりませんね。
共通の価格は、商品名で決まります。
個別の価格は、商品名と売り先で決まります。
関数従属も異なりますし、意味的にも異なるデータです。
異なるデータなので、両方のデータが同時に存在しても、
不都合はありません。
テーブル設計上、それを同じフィールドに入れてる点が問題ですが、
別テーブルに分けても、複雑さはあまり変わりません。
(ビューが2つ減るだけです)
そもそもの内容(要求)が複雑なので、
ある程度複雑なSQLになるのは仕方ないと思いますよ。(^^;
No.3
- 回答日時:
No1回答者です。
とりあえず一番ややこしい所のみ回答しましたが、
その他の部分も結構ややこしいですね。(^^;
順にビューを作っていくのが簡単だと思います。
>条件は各OrderNoについて個数が一番多い商品名とその価格を表示。
各OrderNoの最大個数を調べる
ビュー:最大個数--------------------------
SELECT Order明細テーブル.OrderNO, Max(Order明細テーブル.個数) AS 個数
FROM Order明細テーブル
GROUP BY Order明細テーブル.OrderNO;
------------------------------------------
>もし個数が同じなら、さらに商品名の文字列順序の早い方で1つ選択。
最大個数が重複した場合の商品名の処理
ビュー:最大明細---------------------
SELECT Order明細テーブル.OrderNO, Min(Order明細テーブル.商品名) AS 商品名, Order明細テーブル.個数
FROM Order明細テーブル INNER JOIN 最大個数 ON (Order明細テーブル.OrderNO = 最大個数.OrderNO) AND (Order明細テーブル.個数 = 最大個数.個数)
GROUP BY Order明細テーブル.OrderNO, Order明細テーブル.個数;
------------------------------------------
>OrderテーブルにはOrderNoがあるが明細がない場合は、OrderNo以外ブランク。
LEFT JOIN でブランクの処理
ビュー:Order最大一覧---------------------
SELECT Orderテーブル.OrderNo, Orderテーブル.売り先, 最大明細.商品名, 最大明細.個数
FROM Orderテーブル LEFT JOIN 最大明細 ON Orderテーブル.OrderNo = 最大明細.OrderNO;
------------------------------------------
>価格テーブルに商品の価格が登録されてなかったら、価格部分はブランク。
共通の価格のみ取り出す
ビュー:標準価格テーブル------------------
SELECT 価格テーブル.商品名, 価格テーブル.価格 AS 標準価格
FROM 価格テーブル
WHERE 価格テーブル.売り先="****";
------------------------------------------
個別の価格のみ取り出す
ビュー:個別価格テーブル------------------
SELECT 価格テーブル.商品名, 価格テーブル.売り先, 価格テーブル.価格 AS 個別価格
FROM 価格テーブル
WHERE 価格テーブル.売り先<>"****";
------------------------------------------
最終的な出力
ビュー:集計結果--------------------------
SELECT Order最大一覧.OrderNo, Order最大一覧.売り先, Order最大一覧.商品名, Order最大一覧.個数, 個別価格テーブル.個別価格, 標準価格テーブル.標準価格,
(CASE WHEN 個別価格 is Null THEN 標準価格 ELSE 個別価格 END) As 価格
FROM (Order最大一覧 LEFT JOIN 個別価格テーブル ON (Order最大一覧.売り先 = 個別価格テーブル.売り先) AND (Order最大一覧.商品名 = 個別価格テーブル.商品名)) LEFT JOIN 標準価格テーブル ON Order最大一覧.商品名 = 標準価格テーブル.商品名;
------------------------------------------
ビューの数はもう少し減らせるかもしれませんが、
全部を1つのSQLで表現するのは無理かな。(^^;
なお、私はAccessで動作確認しながら作ったので、
構文の違いなどあれば、読み替えてください。
(分かる範囲でOracle用に書き直してあります)
この回答への補足
返答ありがとうございます。とても参考になりました。
このSQLの場合、もし価格テーブルに求める商品名がなかったらどうなるのでしょうか?
ブランクになると思うんですが自信がなくて。
あと、ややこしい部分となってるところで、価格テーブルには同じ商品について、
'*****'と個別価格の両方の行が絶対ないと仮定した上だとどうなるのでしょうか?
もっと簡単になりますか?
No.2
- 回答日時:
こんにちは。
私も #1 さんのおっしゃるように、設計に問題があると思います。
Orderテーブルと、Order明細テーブルは、
[OrderNo]で結合することができますよね?
そして、Order明細テーブルと価格テーブルは、
[商品名]でしか結合できません。
つまり、ER図で設計を示した場合に、データの関係図が
なっていない、と思うのですが…。
そもそも[売り先]の存在が浮いていませんか?
No.1
- 回答日時:
Oracleには詳しくないので、一般的なSQLの話です。
>次がややこしいです。
ややこしい原因は、価格テーブルの設計にあります。
これはテーブルを分けておく方が良いと思います。
(実際テーブルを分けずにビューを作っても良いです)
標準価格テーブル [商品名]、標準価格
個別価格テーブル [商品名]、[売り先]、個別価格
こうして置けば、価格を決定するのは簡単です。
(CASE WHEN 個別価格 is Null THEN 標準価格 ELSE 個別価格 END) As 価格
#Oracleには詳しくないので、構文が間違っているかもしれませんが、
#意味は伝わるかな。(^^;
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 経営情報システム accessでの請求管理について 12 2022/06/11 16:20
- Visual Basic(VBA) EXCEL関数LOOKUPとFILTERについての質問です 1 2022/12/21 05:53
- Visual Basic(VBA) VBAで質問があります 1 2022/10/19 10:32
- Visual Basic(VBA) VBAコードで質問があります 2 2022/10/20 15:27
- その他(データベース) pythonでsqlight勉強中、クエリー結果の利用法教えて下さい 1 2022/04/28 20:38
- JavaScript テーブルの中のセレクトボックスの値が0のとき、非表示にしたい 3 2022/05/29 10:13
- 大学・短大 至急お願いします 2 2022/04/26 13:59
- PostgreSQL PostgreSQL レコードからアイテム種類数を取得したい 2 2022/11/23 22:31
- テレビ 家電量販店の無料保証3年と5年の違い(液晶テレビ)はどういう基準で決まるのですか? 8 2023/08/06 08:22
- Visual Basic(VBA) VBAで最新のデータを別シートに転記する方法をお教えください。 3 2022/04/07 19:20
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・好きな「お肉」は?
- ・あなたは何にトキメキますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・ハマっている「お菓子」を教えて!
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「マスタ」と「テーブル」の違...
-
重複するキーから一番古い年月...
-
続.ORACLEのSELECTのソートに...
-
2つのテーブルから条件に一致...
-
Accessでフィールドを比較した...
-
主キーの変更
-
ACCESSのSQLで、NULLかNULLでな...
-
DB2でSelectした時(rollback,c...
-
3つ以上のテーブルをUNIONする...
-
データの二重表示の原因
-
ACCESS2007 フォーム 「バリア...
-
オラクルではできるのにSQLSERV...
-
SI Object Browserのテーブルス...
-
SELECT文でのデッドロックに対...
-
sqlserverで集計結果をUPDATEし...
-
Access のリレーションシップで...
-
Accessにインポートしたら並び...
-
インデックスの再構築の意味っ...
-
Access VBA Me.Requery レコー...
-
ADOでSeekメッソッドが使えませ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「マスタ」と「テーブル」の違...
-
2つのテーブルから条件に一致...
-
重複するキーから一番古い年月...
-
ACCESS 一つのフィールドに複...
-
行方向のデータを横に並べる
-
PLSQLの識別子エラー
-
Accessでフィールドを比較した...
-
主キーの変更
-
続.ORACLEのSELECTのソートに...
-
Inner join と Left joinの明...
-
商品コード番号を入力すると商...
-
SQL 2つのテーブルとSUBSTRING...
-
ACCESSのコンパイルエラーについて
-
ACCESS2000でDCount関数の使い方
-
自分自身への矢印
-
請求と入金のテーブルの作成の...
-
Accessユニオンクエリーで2つ...
-
VIEWでテーブルの集計結果...
-
OracleのUnion内でそれぞれのOr...
-
【Access初心者】最大値と次に...
おすすめ情報