Access (一般機能)

Accessの一般機能に関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 10 Home : その他)
主キーの使い方について
投稿日時: 24/03/31 15:08:43
投稿者: Watanabe-45

お世話になります。
職員の人事管理の作業をしており、2つのテーブルをつないだ場合のクエリの表示がよくわからないためご教授いただきたいです。
 
テーブルA【全職員】(主キーは職員ID)
職員ID 職員氏名 住所 ・・・・
 
テーブルB【当月出張ありの職員】(主キーは職員ID)
職員ID 出張@ 出張A・・・
 
 
クエリ出張
SELECT [テーブルB].職員ID, [テーブルA].職員名, [テーブルB].出張@, [テーブルB].出張A
FROM テーブルA INNER JOIN テーブルB ON [テーブルA].職員ID = [テーブルB].職員ID;
 
 
テーブルA、テーブルBともに重複した登録はしたくないため、主キーを使用しています。
テーブルBから主キーを外せば自動的に職員氏名の表示をさせることができるのですが、テーブルBにおいても重複しての登録はしたくないため主キーを設定しました。
テーブルBに職員IDを主キーを設定しつつ、職員氏名を表示させるにはどのようにしたらよいでしょうか。
 
又、同じテーブルに主キーを2つ設定している場合がありますが、どのような場合に複数の主キーを使用するのでしょうか。
 
 
 
 

回答
投稿日時: 24/03/31 17:41:36
投稿者: hatena
投稿者のウェブサイトに移動

Watanabe-45 さんの引用:
テーブルBから主キーを外せば自動的に職員氏名の表示をさせることができるのですが、テーブルBにおいても重複しての登録はしたくないため主キーを設定しました。
テーブルBに職員IDを主キーを設定しつつ、職員氏名を表示させるにはどのようにしたらよいでしょうか。

 
ちょっと意味が理解できないのですが、
現状のSQLで、主キーの設定の有無にかかわらず職員名は表示できていると思いますが。
どのような状況なのでしょうか。
 
職員名が表示されない場合の、テーブルAとテーブルBのデータ例を提示してもらえますか。
 
そもそもテーブル設計に問題がありそうですが、とりあえず現状の状況の把握が先決です。

投稿日時: 24/03/31 20:18:52
投稿者: Watanabe-45

hatenaさん
 
ありがとうございます。
 
クエリ出張で職員IDを入力時、テーブルBに主キーを設定しない場合は職員名が都度表示されるが、テーブルBの職員IDを主キーに設定すると、クエリ出張の職員ID入力時に職員名が表示されない設定となってしまいます。
Requery をすれば表示されるのですが、最初のレコードに戻ってしまい使い勝手が悪いです。
拙い説明ですが、現在このような状況です。
 

回答
投稿日時: 24/04/01 01:21:09
投稿者: hatena
投稿者のウェブサイトに移動

質問のようなテーブルの関係を一対一といいますが、データベースでは通常はそのような関係のデータは一つのテーブルにまとめます。
 
質問のように2つに分ける場合、
テーブルAがメインで、テーブルBがサブという関係になります。
テーブルAにない職員IDは、テーブルBでは入力できないという設定になります。
つまり、テーブルAの職員IDから先に入力しなければならないという規制がはいります。
クエリとしては下記のような設計になります。
 

SELECT テーブルA.職員ID, テーブルA.職員名, テーブルB.出張@, テーブルB.出張A
FROM テーブルA LEFT JOIN テーブルB ON テーブルA.職員ID = テーブルB.職員ID;

 
詳細は長くなるのので、下記のリンク先を参照してください。
 
一対一関係のテーブル設計 - hatena chips
https://hatenachips.blog.fc2.com/blog-entry-29.html
 
しかし、職員の出張データの管理としては、このような設計はデータベース的にはNGです。
出張データとしては、出張先、出張開始日、業務内容、旅費、などのデータが必要になります。
また、一人の職員が何回も出張することは当然あるはずです。
それらをすべてテーブルに格納しようとするとフィールド数が非常に多くなります。
フィールド数の条件は255までという制限があるし、フィールド数が多いと、集計や検索などの処理が非常に面倒になります。
 
このような場合は、一対多の関係になるような設計にします。
一例をあげると下記のような感じにです。
 
職員マスタ
 職員ID (主キー)
 氏名
 住所
 ・・・
 
出張履歴
 職員ID   (主キー)
 出張開始日 (主キー)
 出張期間
 出張先
 業務内容
 旅費
 ・・・
 
 
 

投稿日時: 24/04/01 22:54:10
投稿者: Watanabe-45

hatenaさん
度々のコメントありがとうございます。
 
出張者のテーブルには当月の該当職員のみのテーブルを作っておりました。
メインのテーブルAとテーブルBは1対1ではないデーブルで行っておりました。
出張対象者の該当者の職員IDを入力してクエリを作ろうとしておりましたが、1対1のテーブルでないとよろしくないという意見をいただきましたので、週末に作り直しをしたいと思います。

回答
投稿日時: 24/04/02 00:39:57
投稿者: hatena
投稿者のウェブサイトに移動

うまく伝わっていないかもしれませんので、補足します。
 
現状のテーブルのフィールド構成は一対一の設計になってます。
 
それでは、使い勝手が悪いのではないかと思いますが、その点にどうお考えでしょうか。
 
一人の職員は、出張は一回だけとは限りませんよね。1回も出張しない人や、何十回も出張する人など、いろいろいますよね。
 
また、現状の出張@ 出張A・・・フィールドにどのようなデータが入るのか不明ですが、
出張先とか、出張日とか、旅費とか、などのデータも必要ですよね。
 
つまり、職員データ(氏名、住所・・・・)と出張データは、一対一の関係ではなく、一対多の関係ということです。
このようなデータに対応するためには、テーブル設計も一対多の設計にすべきだと思います。
 
一対多のテーブル設計の例は前の回答で提示してあります。
(一例ですので実態にあわせて改修する必要はあるかも知れません。)
 
テーブル設計はデータベースの基本ですので、これが間違っているとデータベースとして使い物にならないものになります。

回答
投稿日時: 24/04/02 00:43:17
投稿者: MMYS

Watanabe-45 さんの引用:
張ありの職員】(主キーは職員ID)
職員ID 出張@ 出張A・・・

通常、テーブルの設計で、出張@・出張A のように同じ項目を複数用意してはいけません。なぜなら出張が増えるたびに項目を増やすのですか。
 
そして、同じ出張で、一人で行くことも、上司と二人で、または複数人で行くこともあるでしょう。
 
また、主キーは目的はレコードに一意の値をつけることでレコードの特定で目的です。主キーはテーブル設計で重要な項目ですが、重複防止のために容易されたものではありません。
重複を防ぐには、ユニークキーを設定します。主キーはユニークキーでもありますが、目的が異なるので、適切に設計しましょう。
 
設計として、以下のような例が考えられます。
 
 
職員テーブル
 職員ID    主キー(PK)
 氏名
 住所
 
出張内容テーブル
 出張ID    主キー(PK)
 日付
 内容
 
出張関連テーブル
 職員ID    主キー・外部キー(FK)
 出張ID    主キー・外部キー(FK)
 
 
テーブル内容として、例えば下記の場合
 
職員テーブル
職員ID  氏名    住所
1001    鈴木    〇〇
1002    佐藤    □□

出張内容テーブル
出張ID  日付          内容
1       2024/04/01    △△視察
2       2024/04/02    〇〇講習

出張関連テーブル
職員ID  出張ID
1001    1
1001    2
1002    2

 
以下のクエリを実行。
 
SELECT
  職員テーブル.氏名
, 出張内容テーブル.日付
, 出張内容テーブル.内容
FROM
 職員テーブル INNER JOIN
 (出張内容テーブル INNER JOIN 出張関連テーブル
  ON 出張内容テーブル.出張ID = 出張関連テーブル.出張ID)
 ON 職員テーブル.職員ID = 出張関連テーブル.職員ID;
 
クエリ結果
氏名    日付          内容
鈴木    2024/04/01    △△視察
鈴木    2024/04/02    〇〇講習
佐藤    2024/04/02    〇〇講習

 
鈴木は△△視察、〇〇講習に出張
佐藤は〇〇講習に出張
△△視察は鈴木が一人のみ
〇〇講習は鈴木・佐藤の2名。
 

回答
投稿日時: 24/04/02 16:44:09
投稿者: Suzu

Watanabe-45 さんの引用:
出張者のテーブルには当月の該当職員のみのテーブルを作っておりました。

 
そんな方法も もちろん あります。
その場合、月が変わったら、テーブルなり、クエリを作り替える 必要が出てきませんか?
或いは、ファイル自体をコピーして 年月毎にファイルを分けるなんて使い方でしょうか?
 
データベースとしてはそれは使いづらいのです。
データベースは、データ量(レコード数)が多い事を前提として 使われます。
年月毎 に テーブルやクエリ を作り変える事なく 使える様にしたいです。
 
行うなら、クエリにて、年月の抽出条件を入力し
その抽出条件のデータを表示させる というのが データベース【らしい】使い方 となります。
 
 
テーブルの作り方ですが
 
・どこまでのデータを持たせるか
・入力順も含め検討が必要です。
 
 
MMYS さん ご提案の
引用:
職員テーブル
職員ID 氏名 住所
1001 鈴木 〇〇
1002 佐藤 □□
 
出張内容テーブル
出張ID 日付 内容
1 2024/04/01 △△視察
2 2024/04/02 〇〇講習
 
出張関連テーブル
職員ID 出張ID
1001 1
1001 2
1002 2
 
 
氏名 日付 内容
鈴木 2024/04/01 △△視察
鈴木 2024/04/02 〇〇講習
佐藤 2024/04/02 〇〇講習

 
鈴木・佐藤 が 同じ日 同じ講習 に出た場合
 鈴木の入力が 終わった時点で、
 
  出張内容テーブル
出張ID 日付 内容
2 2024/04/02 〇〇講習
 
が 入力されていますので、 日付・内容 を再び入力する必要はありません。
そういう意味では、楽です。
 
でも、逆に言うと
氏名 日付 内容
鈴木 2024/04/01 △△視察
の入力時には
 
引用:
出張内容テーブル
出張ID 日付 内容
1 2024/04/01 △△視察
を入力後に
 
引用:
出張関連テーブル
職員ID 出張ID
1001 1
の入力を行う必要があります。
 
他に、
入力内容に、費用金額 を入れる様にしたい。
鈴木・佐藤 の 出張費用が違う場合
 
上記の構成では 同じ出張なら、同じ日付・同じ費用になってしまいます。
 
 
・どんな項目まで入力したいか。
・その中で何が共通なのか
をきちんと分析した上でテーブル構造を決める様にしましょう。

投稿日時: 24/04/08 23:09:45
投稿者: Watanabe-45

hatenaさn
MMYSさん
Suzuさん
コメントありがとうございます。
 
MMYS さん ご提案複数テーブルも作成してみましたが、1つにまとめたほうがデータを入力しやすいため1対多のテーブルで運用することとしました。
力不足でテーブルの構造や項目などうまく説明できずにすみません。
入力用テーブルは主キーは設定せずに作っていきたいと思います。