• 締切済み

表と表の結合について

新人研修で、「表の結合の際に、結合する列がなぜその列なのか?」を説明する方法を悩んでおります。 <元表> 商品コード、商品名、購入数、顧客情報 <正規化> 商品テーブル:商品コード、商品名 売り上げテーブル:商品コード、購入数量、顧客I これを見たとき、私は 「商品コード」で 結合すれば、「どこ顧客が、何の商品」を購入されたかというのがわかるのですが、 [質問1] なぜ商品コードで、「結合する仕様になっているか」の説明を求められたとき うまく説明する方法が思いつきません・・・。 「売り上げ伝票から正規化されて作成されたから、正規化する前の情報を出せるように関連付けするために、主キーの商品コードを、各表2つに残しておく。」 と言う説明しか出来ないのです。 もっとわかりやすい説明がありましたらご教授のほうお願いします。 できれば、正規化と言う情報を使わずに、「商品コード」で結合する理由を説明したいのです。

みんなの回答

  • jjon-com
  • ベストアンサー率61% (1599/2592)
回答No.3

質問文に <元表> と <正規化> が載せてありますけれど,正規形が必ずそれになるとは言えないです。前提条件が変われば正規形も変わりますから。 次の3つの例を検討してみます。 ▼条件1 ・1つの商品はただ1人の顧客だけが購入できる ▼条件2 ・1つの商品は複数の顧客が購入できる ・1人の顧客は同一商品をただ1度だけ購入できる ▼条件3 ・1つの商品は複数の顧客が購入できる ・1人の顧客は同一商品を複数回購入できるが,1日あたりの同一商品の購入は1度だけ それぞれの場合,正規形の例は次のようになります。 ▼条件1の正規形 商品コードが決まればそれに対応する商品名,購入数,顧客コードすべて一意に決まります。 イメージとしては,オークションにおける出品と同じく,まったく同じ書籍が複数出品されたとしてもそれぞれ別々の商品コードが割り振られる条件だということです。 関数従属ではこれを,商品コード →(商品名,購入数,顧客コード)のように表現します。 したがって,この条件における正規形は「商品コード,商品名,購入数,顧客コード」です。複数の表には分離されません。 ▼条件2の正規形 商品:購入 の対応は 1:N です。 商品名は,商品コードが決まれば一意に決まりますが, 購入数は「商品 SH01 を顧客 KY01 が 10個購入」「商品 SH01 を顧客 KY02 が 20個購入」のように, 商品コードが決まっただけではダメ,顧客コードが決まっただけでもダメで,商品コードと顧客コードのペアが決まると購入数が一意に決まります。 それぞれを関数従属で表現すれば次のようになります。正規形の2つの表もこうなります。 商品コード→商品名 (商品コード,顧客コード)→ 購入数 ▼条件3の正規形 質問文で挙げられた次の表は,   > <正規化>   > 売り上げテーブル:商品コード、購入数量、顧客I 次のような現象が起こることを想定していません。 「【1月23日に】商品 SH01 を顧客 KY01 が 10個購入」 「【1月24日も】商品 SH01 を顧客 KY01 が 10個購入」 そういう現象が発生するのなら,購入日付の情報を持たねばなりません。 関数従属 および 正規形 は次のようになるでしょう。 商品コード→商品名 (商品コード,顧客コード,購入日付)→ 購入数 それでも「同一顧客による1日あたりの同一商品の購入は1度だけ」という制限は残ります。 1日に何度も購入が発生する状況であるなら,購入の時分秒まで含めるなり,購入トランザクション毎に購入コードを割り当てるなりする必要があります。 ---------------------------------------- 以上,述べてきましたが,結論としては, > 正規化する前の情報を出せるように関連付けするために、 > 主キーの商品コードを、各表2つに残しておく。 という人間の意図で商品コードを2つの表に含ませているのではなく, 元表の項目を分析したら,主キーが異なる2つのグループに分離されたから,2つの表に分割したのだ,ということになります。 > なぜ商品コードで「結合する仕様になっているか」 という質問が出てくるということは,購入数という項目が「何に対する」購入数なのかを理解していないということだと思います。

ShiftTail
質問者

お礼

正規化の指摘ありがとうございます。 > なぜ商品コードで「結合する仕様になっているか」 という質問が出てくるということは,購入数という項目が「何に対する」購入数なのかを理解していないということだと思います。 少し考えて見ます。ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • Siegrune
  • ベストアンサー率35% (316/895)
回答No.2

う~ん、「なぜ商品コードで、結合する仕様になっているか」と聞かれるようなレベルなら、 その前に、なぜ商品コードが元表に必要かを先に説明したほうがいいのでは? 注文って普通商品名と数量をお客さん(顧客情報)からもらいますよね。 そこに商品コードなんて出てきません。 (お客さんとこちらで商品コードが一致するとも限りませんし。) 実をいうと、商品名が非常に短い(例えば型番など)場合、 「商品コード」で結合する必然性はありません。 ※例えば、世の中には、1製品しか作っていない製造業がまれにあって (製薬業とかであるのを知っているのですが。)、 製品の種別は100錠入り、200錠入り・・・しかありません等ということもあります。 これなら、ABC-100、ABC-200・・・で製品名がすんでしまいます。 このとき、製品コードって本当に必要? ということで説明をしようとすると <元データ> 商品名、購入数、顧客情報 ↓ 商品名は文字数が多いから、商品コードを入力して指定したほうが楽。 顧客情報も毎回住所や名前を入力するのが面倒だから顧客コードを指定するほうが楽。 ↓ <元表> 商品コード、商品名、購入数、顧客コード、顧客情報 ↓ 同じ商品コードと商品名が、同じ顧客コードと顧客情報がいっぱい入っている。 ↓ <正規化> 商品テーブル:商品コード、商品名 顧客テーブル:顧客コード、顧客情報(住所、氏名等) 売り上げテーブル:商品コード、購入数量、顧客コード あるいは、 <元データ> 商品名、購入数、顧客情報(住所、氏名等) ↓ 同じ商品名や、同じ顧客情報がいっぱい入っている。 同じ商品名は商品コードをつけて、短い文字数で表すと、簡単になる。 同じ顧客情報は顧客コードをつけると、住所や氏名という複数の文字数が多い情報が、 短い文字数であらわすことができる。 ↓ (間に<元表>を入れるべきかどうかは悩ましいですが。) ↓ <正規化> 商品テーブル:商品コード、商品名 顧客テーブル:顧客コード、顧客情報(住所、氏名等) 売り上げテーブル:商品コード、購入数量、顧客コード といった感じでどうでしょう。

ShiftTail
質問者

お礼

>う~ん、「なぜ商品コードで、結合する仕様になっているか」と聞かれるようなレベルなら、 その前に、なぜ商品コードが元表に必要かを先に説明したほうがいいのでは? ちょっとこれについて説明するということで考えて見ます。 後は、正規化のやり方については確かに商品コードに商品名が入るケースも考えられますね。 ありがとうございます。

全文を見る
すると、全ての回答が全文表示されます。
  • toshi_2000
  • ベストアンサー率30% (306/1002)
回答No.1

商品名が変更になった場合、正規化した場合は、商品テーブルの1レコードのみを変更すれば済みます。 正規化しなかった場合、元表にある複数のレコード全ての商品名を変更する必要があります。 こんな説明で分かりますか?

ShiftTail
質問者

お礼

回答ありがとうございます。 確かに正規化する理由としては、教えて頂いた内容で問題ないと思いました。 ただ、結合する列の説明がやはりできないので、考えて見ます。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • アクセスのクエリの作り方

    初心者なので教えてくださいませんか? アクセスでテーブルを複数作成して、それをクエリで結合するときに、どのテーブルからどのフィールドを選べばいいのかわかりません。 例えば・・・ 売上テーブル:NO 売上日 商品コード 数量 商品テーブル:商品コード 商品名 単価 この二つのテーブルを結合するクエリを作ります。 NO 売上日 商品コード 商品名 単価 数量 上記のフィールドを使用したいのですが、このとき、商品コードをどちらのテーブルのを使ったらよいのでしょう。 その判断は何からしたらよいのでしょうか。 うまく説明できているかわかりませんが、よろしくお願いします。

  • Accessのテーブル結合方法

    Access2000で商品の仕入と売上の受払を一覧表にしようとしているのですがうまくいきません。 テーブルは商品仕入と、売上の2つがあって 仕入には荷受した日、商品コード、数量、仕入金額と値入金額、仕入先があります。 売上には売上した日、商品コード、レジ番号、利用者、数量、売上金額となっています。 この2つを1枚の表にして、商品コード別に在庫が動いた日、適用(売上ならレジ番号、利用者を表記して、仕入なら仕入先を明記)、仕入数量、仕入金額、値入金額、売上数量、売上金額となるようにしたいのですが、うまくいきません。 ユニオンクエリを使ったり、選択クエリで単純にならべたりしたのですが、私の知識ではどうにもならなくなりました。 よろしくご指導のほどお願いします。

  • Accessで、在庫表を作りたいのですが・・・

    いつも大変お世話になっております。m(_ _)m また質問させてください。 Accessで、在庫表を作っています。 「入庫情報_テーブル」と「出庫情報_テーブル」があり、それぞれのテーブルは、製品名(型番)と数量の情報を持っています。 入庫情報の数量はプラスして、出庫情報の数量はマイナスして、差引きの在庫表を作りたいのですが・・・ 入庫情報に入っている製品名のすべてを表示して、出庫情報の数量をマイナスする・・・というのは、「結合のプロパティ」で、入庫情報の全レコードと・・・というオプションを選べば可能です。 またその逆も可能なわけですが、両方を全部表示したい時はどうすればいいのでしょうか? つまり、入庫情報に入力されている商品で出庫情報にのっていないものと、出庫情報に入力されている商品で入庫情報にのっていないものがあるわけです。 在庫表では、それぞれのテーブルに存在するすべての製品名を載せ、型番が合致した場合は、入庫数量-出庫数量で在庫を出したいのです。 出庫情報にあって、入庫情報にないものというのは、つまり、在庫数がマイナスになるということです。 両方を同時に満たすには、どのようにすればいいのでしょうか? 質問の説明文が不足していたら指摘してください。 よろしくお願いします。

  • 行をまとめる計算式

    エクセルで以下のような表があるとします。 顧客 商品名 販売数量 コスト 売単価 売上 ああ かかか 10 200 300 3000 ああ ききき 10 300 400 4000 いい かかか 10 200 300 3000 いい かかか 10 200 300 3000 いい ききき 10 300 400 4000 うう かかか 10 200 300 3000 うう ききき 10 300 400 4000 うう ききき 10 300 400 4000 うう ききき 10 300 400 4000 この表を以下のようにするにはどうしたらいいでしょうか? 顧客 商品名 販売数量 コスト 売単価 売上 ああ かかか 10 200 300 3000 ああ ききき 10 300 400 4000 いい かかか 20 200 600 6000 いい ききき 10 300 400 4000 うう かかか 10 200 300 3000 うう ききき 30 300 400 12000 つまり、顧客と商品名が同一の行は、販売数量と売上を合計して一行にまとめてしまいたいと考えています。 上記の表からは分からないようになっていますが、売単価は基本的に顧客ごとに違います。コストは同じ顧客の中でも違うことがあり、顧客と商品名が同一の行があった場合、その平均値を出したいと考えています。 一番目の表を元に別シートに二番目の表を作成したいと考えています。 二番目の表のそれぞれの列にどのような計算式を入れればいいでしょうか? ご教示お願いいたします。

  • エクセルで作成した「月間売上高表」から「顧客別売上高表」を作成する方法

    「月間売上高表」のA列:顧客名、B列:代金、C列:商品名を入力しました。  この表から「顧客別 月間売上高表」を作成する方法を教えてください。

  • Accessで複数テーブルのJoin

    次のようなテーブル(T1~T4)とクエリ(Q1~Q2)があります。 クエリの表で囲っているものはAccessのQBEを表しています。 その下はAccessが自動生成したSQLです。 Accessがある場合はいいのですが、ない場合、いきなりSQLを 書かないといけないわけですが、どのような順番に並べていって いいのか整理がつきません。 4つ以上になるとさっぱりです。 何かヒントをいただけませんでしょうか? T1:売上表[売上No、日付、顧客CD] T2:顧客表[顧客CD、顧客名] T3:売上明細[ID、売上No、連番、商品CD、数量] T4:商品表[商品CD、商品名、単価] Q1: ┌────────────────┐ │日付 │ 商品名│単価 │数量 │ ├────────────────│ │売上表│商品表│商品表│売上明細│ └────────────────┘ SELECT 売上表.日付, 商品表.商品名, 商品表.単価, 売上明細.数量 FROM 商品表 INNER JOIN (売上表 INNER JOIN 売上明細 ON 売上表.売上No = 売上明細.売上No) ON 商品表.商品CD = 売上明細.商品CD; Q2: ┌────────────────────┐ │日付 │ 顧客名│商品名│単価 │数量 │ ├────────────────────│ │売上表│顧客表│商品表│商品表│売上明細│ └────────────────────┘ SELECT 売上表.日付, 顧客表.顧客名, 商品表.商品名, 商品表.単価, 売上明細.数量 FROM (商品表 INNER JOIN (売上表 INNER JOIN 売上明細 ON 売上表.売上No = 売上明細.売上No) ON 商品表.商品CD = 売上明細.商品CD) INNER JOIN 顧客表 ON 売上表.顧客CD = 顧客表.顧客CD;

  • ACCESS 顧客データ 購入履歴検索について

    ACCESSで顧客データを管理しています。 ●月●日以降 ○○製品の購入履歴があった人が、 その日付以降に再来店しているか、再来店日、購入製品をだしたいのですが、 良い抽出方法ありますか? テーブルには、↓ があります。 顧客コード 顧客名 売上日付 取引番号 商品コード 商品名 売上数量 店舗名  分かる方いらしたら教えて下さい! 宜しくお願いします。

  • アクセスのリレーションシップ

    アクセス2007を使用しています。 顧客表 (顧客コード 顧客名) 注文表 (顧客コード 商品名 数) と言う表があります。 二つの表を 1.リレーションシップをはる 2.結合する(クエリ:売上表) 上記作業を行い売上表を作成しました。 売上表作成の流れは、 「当然顧客コードで2つの表が結合され、両方の表に存在する値の行が表示される」 と思っております。 今回の結合(等結合)表の作り方は以下の流れだと思っております。 1. 顧客表、注文表の直積を出す。 2. 顧客表・注文表の顧客コードで一致する行を抽出する。 ここで質問なのですが、 一度、リレーションシップを作成しないで、 顧客表と、注文表を結合しようとし、クエリの売上表を作成しようとしました。 すると、直積結果までしか出ませんでした。 (SQLウィザードを確認しましたが、FROM句までのSQLしかありませんでした。Where,Innnerなし) これはつまり、リレーションシップを張らなければ、等結合が行われないということで 間違いないでしょうか?(Where、Inner JOINでの条件が入らない)

  • 表の結合の仕方

    お世話になります。 このたび今後の業務に必要な為、SQLを勉強することになりました。そこでこのような問題が出たのですがどうも理解できません。 【商品マスタ】 商品コード 商品名  単価 0001    ボール  100 0002    バット  200 0003    グローブ 300 【仕入先マスタ】 仕入先コード 仕入先 001      A 002      B 003      C 【トラン】 購入番号  商品コード 仕入先コード 数量 1      0001    001      1 2      0001    002      2 3      0001    003      3 4      0001    001      4 5      0001    002      5 6      0002    003      6 7      0002    001      7 8      0002    002      8 9      0003    003      9 10      0003    001      10 11      0004    004      20 上記の商品、仕入先、トランのテーブルから以下のように出力をするものです。 商品コード、商品名、仕入先コード、仕入先名、数量、単価、金額 0001 ボール  001 A    5 100  500 0001 ボール  002 B    7 100  700 0001 ボール  003 C    3 100  300 0002 バット  001 A    7 200  1400 0002 バット  002 B    8 200  1600 0002 バット  003 C    6 200  1200 0003 グローブ 001 A    10 300  3000 0003 グローブ 003 C    9 300  2700 0004 (null)  004 (null) 20 (null) (null) ネットを見てもいまいちピンと来ず行き詰っています。ヒント等ありましたらよろしくお願い致します。

  • クエリー列選択の基準

    顧客表 (顧客コード 顧客名) 注文表 (顧客コード 商品名 数) の表から 売り上げクエリー(ビュー)を作成しようと考えています。 (注文表に、ON UPDATE CASCADE設定済み) 1.表示クエリーを作成する場合  {顧客表.顧客コード , 顧客名 , 商品名 , 数}  or  {注文表.顧客コード , 顧客名 , 商品名 , 数} どちらの列で作成しても問題ないと思います。 2.更新クエリを作成しようとする場合  (1).{顧客表.顧客コード , 顧客名 , 商品名 , 数}  or  (2).{注文表.顧客コード , 顧客名 , 商品名 , 数}    ・表作成後、顧客コードを更新すると考えた場合  (1)の場合は、顧客コードのマスター列を更新するため、子表:注文表の列も更新されるためエラーは起きないと考えています。  (2)の場合は、注文表の顧客コードの更新になるため、更新エラーになると考えています。 質問:検索クエリー(ビュー)を作成する場合は、特に列の選択は気にしなくてもいいと思っているのですが、 更新クエリーを作成する場合は、(1)(2)のようなケースがあると思っています。 更新クエリーの列の選択は、更新エラー等まで考えて列選択をしたほうがいいのでしょうか。 (親表の列を、使用するという考えでは雑でしょうか。)