Access (VBA)

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

 
(Windows 10 Home : Access 2000)
SQLで複数条件での結合について教えてください
投稿日時: 19/05/27 11:05:39
投稿者: KUMAKUMA

こんにちは、SQL構文での質問です。
 
テーブルは以下の「購入テーブル」と「名称マスタ」の2種類です。
 
 
購入テーブル
氏名ID 購入ID 購入数
1 2 3
3 1 1
2 3 1
 
 
名称マスタ
区分 ID 名称
1 1 田中
1 2 鈴木
1 3 山本
2 1 ノート
2 2 ペン
3 3 消しゴム
 
 
最終的に欲しいテーブルは 上記2つのテーブルを結合して
 
氏名 購入品 購入数
田中 ペン 3
山本 ノート 1
鈴木 消しゴム 1
 
 
のようにしたいです。
 
 
 
氏名だけでしたら
SELECT 名称 AS 氏名,購入ID,購入数
FROM ( SELECT * FROM 名称マスタ WHERE 区分=1 )
WHERE 購入テーブル.氏名ID=名称マスタ.名称
 

氏名 購入ID 購入数
田中 2 3
山本 1 1
鈴木 3 1
 
とするのは想像できるのですが、氏名IDと購入IDを
両方「名称マスタ」から区分を変更して結合させる方法が
わかりません。
 
SQL構文のアドバイスいただけないでしょうか
よろしくお願いします。
    
KUMAKUMA
 
 

回答
投稿日時: 19/05/27 11:29:55
投稿者: sk

引用:
最終的に欲しいテーブルは 上記2つのテーブルを結合して
  
氏名 購入品 購入数
田中 ペン 3
山本 ノート 1
鈴木 消しゴム 1
  
  
のようにしたいです。

( SQL ビュー)
------------------------------------------------------------------
SELECT [購入者マスタ].[氏名],
       [商品マスタ].[商品名] AS [購入品],
       [購入テーブル].[購入数]
FROM ([購入テーブル]
      LEFT JOIN (SELECT [名称マスタ].[ID] AS [購入者ID],
                        [名称マスタ].[名称] AS [氏名]
                 FROM [名称マスタ]
                 WHERE [名称マスタ].[区分] = 1) AS [購入者マスタ]
      ON [購入テーブル].[氏名ID] = [購入者マスタ].[購入者ID])
LEFT JOIN (SELECT [名称マスタ].[ID] AS [商品ID],
                  [名称マスタ].[名称] AS [商品名]
           FROM [名称マスタ]
           WHERE [名称マスタ].[区分] <> 1) AS [商品マスタ]
ON [購入テーブル].[購入ID] = [商品マスタ].[商品ID];
------------------------------------------------------------------
 
こんなややこしいサブクエリを記述するより、
[購入者マスタ]や[商品マスタ]に当たるテーブル
(あるいは選択クエリ)を別途作成して、
[購入テーブル]と外部結合させるようにした方が
判りやすいと思いますが。

回答
投稿日時: 19/05/27 14:08:58
投稿者: Suzu

質問者さんは、WHERE句で結合していますので、それにならって・・
 
SELECT
    [購入テーブル].[氏名ID], [氏名マスタ].[名称] AS [氏名],
    [購入テーブル].[購入ID], [商品マスタ].[名称] AS [購入品],
    [購入テーブル].[購入数]
FROM
    [購入テーブル], [名称マスタ] AS [氏名マスタ], [名称マスタ] AS [商品マスタ]
WHERE
    ([購入テーブル].[氏名ID] = [氏名マスタ].[ID] AND [氏名マスタ].[区分] = 1)
    AND
    ([購入テーブル].[購入ID] = [商品マスタ].[ID] AND [商品マスタ].[区分] = 2)
 
sk さんの、回答でもそうですが、
FROM句 にて、名称マスタ テーブル を二つ配置しているのが味噌です。
片方は 氏名抽出、もう片方で 商品名 を抽出しています。
 
ただ・・
上記は 内部結合
 
SELECT
    [購入テーブル].[氏名ID], [氏名マスタ].[名称] AS [氏名],
    [購入テーブル].[購入ID], [商品マスタ].[名称] AS [購入品],
    [購入テーブル].[購入数]
FROM
    (
        [購入テーブル]
        INNER JOIN
        (
            SELECT [氏名マスタ].[ID], [氏名マスタ].[名称]
            FROM [名称マスタ] AS [氏名マスタ]
            WHERE [氏名マスタ].[区分]=1
        )
    )
    INNER JOIN
        (
            SELECT [商品マスタ].[ID], [商品マスタ].[名称]
            FROM [名称マスタ] AS [商品マスタ]
            WHERE [商品マスタ].[区分]=2
        )
 INNER JOIN と結果が一緒になります。
 
  ※ 内部結合:両方のテーブルに結合するキーの値がないと抽出されません。
 
今回の例、消しゴムの区分は「2」であるべきが、「3」となっている。
 
内部結合の場合、[商品マスタ].[ID] の抽出条件が3なので、商品マスタ側では、「1」と「2」しかありません。
 
なので結果としては
 
1 田中 2ペン 3
3 山本 1ノート 1
 
しか返ってきません。
 
外部結合の場合、得られる結果は
1 田中 2ペン 3
3 山本 1ノート 1
2 鈴木 3    1
となります。
 
どちらが良いのかは、システムの要件なのでしょうね。
 
前者は、一致した確実なデータのみを 表示 データに間違いはない。が間違いには気づきにくい。
後者は、その逆になります。
 
どっちにしても、いろいろクエリを作り、クエリをSQLビューに変更し
SQLの中身を確認しSQLを勉強していってください。

投稿日時: 19/05/28 10:13:17
投稿者: KUMAKUMA

skさん、Suzuさん
非常に的確な回答ありがとうございました。
 
どちらでも実現できました。
ただ、今回は内部結合が適切でしたのでINNERを採用しました。
 
> sk さんの、回答でもそうですが、
> FROM句 にて、名称マスタ テーブル を二つ配置しているのが味噌です。
> 片方は 氏名抽出、もう片方で 商品名 を抽出しています。
 
ここがなかなかしっくり理解しにくいところです・・
 
それと内部結合と外部結合についても理解できました。
 
skさんがおっしゃるように別テーブルですれば解決なのですが
他と共通で使っているテーブルからの抽出なので仕方なくです。
 
skさん、Suzuさん
本当にありがとうございました。感謝です。