1170050419 SQL の表の結合について教えてください。


売上1件1件の発生日時を記録したテーブルAと、売上1件1件の金額を記録したBという2つのテーブルがあるのですが、AからBへはコードではなく次のように行番号によってレコードを参照しているという状況です。

[テーブルA(売上日時データ)のフィールド]
・顧客コード
・売上発生日時
・行番号
(「行番号」は、テーブルB内から該当顧客に対するレコードを抽出したとき、その中の何番目のレコードがこのレコードに対応するかを表す)

[テーブルB(売上金額データ)のフィールド]
・顧客コード
・金額

これら2つのテーブルを元に「顧客コード」「売上発生日時」「金額」を並べた情報を取得したいのですが、「SELECT」一発で決まるようなスマートな方法はあるでしょうか?

一応、ACCESSでの話ですが、SQLの一般論でも結構です。テーブルA、Bの構造は変えることはできないので、DBの設計からやり直せ、という回答はご遠慮ください。

★ 補足のため具体例を画像として添付します。

回答の条件
  • 1人3回まで
  • 登録:
  • 終了:2007/01/31 17:56:35
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:b-wind No.3

回答回数3344ベストアンサー獲得回数440

ポイント80pt

コメントに有るように入力日時カラムが存在し、同じ顧客コードで同一時刻は無いものとして扱います。(出なければまともに検索できませんので)

また、入力日時は昇順で行番号を振ります。


SELECT A.顧客コード,A.売り上げ発生日時,
        B.金額
  FROM テーブルA AS A
   JOIN
     ( SELECT 顧客コード,金額,
       ( SELECT count(*) FROM テーブルB AS B2
           WHERE B2.入力日時 < B1.入力日時
       )+1 AS 行番号
        FROM テーブルB AS B1
       ORDER BY B1.入力日時
     ) AS B
   USING ( 顧客コード,行番号 );

Access で動くかどうかは試してないので分かりません。

コスト度外視なのは元の設計が原因なので諦めてください。

id:you1982

ありがとうございます!

まだACCESSで試していませんが、効率はともかく、たぶんこれが1番、簡単なSQL文のように見えますね。

おそらくこのb-windさんのご回答で問題解決だと思うのですが、引き続き、Access独自の方法やあるいは裏技(?)的にダイレクトに行番号から引っ張れるような方法がありましたらお願い致します。

2007/01/30 01:10:48

その他の回答2件)

id:inokuni No.1

回答回数1343ベストアンサー獲得回数21

LEFT JOIN 等でテーブルを結合すればいいのではないでしょうか?

http://makotowatana.ld.infoseek.co.jp/access/dasqlleftrightjoin....

SELECT
	テーブルA.顧客コード,
	テーブルA.売り上げ発生日時,
	テーブルB.金額
FROM	テーブルB
LEFT JOIN	テーブルA
ON	テーブルB.顧客コード = テーブルA.顧客コード
id:you1982

上記の例ですと、テーブルB側のレコードが一意に特定されないためうまくいかないのではないでしょうか?

2007/01/29 16:26:43
id:inokuni No.2

回答回数1343ベストアンサー獲得回数21

質問者:you1982 2007-01-29 16:26:43

上記の例ですと、テーブルB側のレコードが一意に特定されないためうまくいかないのではないでしょうか?

テーブルBに一意に特定できる主キーのようなものが示されていないので、

一意に特定できないのはいたしかたないかと思います。


テーブルBが何の順番で並んでいるのかもよく分かりませんし。

id:you1982

そのような状況下で何とかしたい、というのが質問の趣旨でした。

コメントで触れたのですが、テーブルBのソート順については一意にソート可能と考えてください。

2007/01/29 16:44:14
id:b-wind No.3

回答回数3344ベストアンサー獲得回数440ここでベストアンサー

ポイント80pt

コメントに有るように入力日時カラムが存在し、同じ顧客コードで同一時刻は無いものとして扱います。(出なければまともに検索できませんので)

また、入力日時は昇順で行番号を振ります。


SELECT A.顧客コード,A.売り上げ発生日時,
        B.金額
  FROM テーブルA AS A
   JOIN
     ( SELECT 顧客コード,金額,
       ( SELECT count(*) FROM テーブルB AS B2
           WHERE B2.入力日時 < B1.入力日時
       )+1 AS 行番号
        FROM テーブルB AS B1
       ORDER BY B1.入力日時
     ) AS B
   USING ( 顧客コード,行番号 );

Access で動くかどうかは試してないので分かりません。

コスト度外視なのは元の設計が原因なので諦めてください。

id:you1982

ありがとうございます!

まだACCESSで試していませんが、効率はともかく、たぶんこれが1番、簡単なSQL文のように見えますね。

おそらくこのb-windさんのご回答で問題解決だと思うのですが、引き続き、Access独自の方法やあるいは裏技(?)的にダイレクトに行番号から引っ張れるような方法がありましたらお願い致します。

2007/01/30 01:10:48
  • id:taknt
    >DBの設計からやり直せ、という回答はご遠慮ください

    ま、回答じゃなくコメントなので・・・。


    テーブルBには 行番号が必要である。
    つまり、テーブルBが どれでソートされた状態かで 取得する内容が 変わる おそれが あるからだ。

    テーブルBには 行番号と似たようなものを 追加すべきである。
    もちろん、行番号で 抽出させることも 可能だと思うが・・・
    (オラクルなら ROWNUM(行番号)というのが あるので それを使えばいい。ACCESSにも似たようなのが あるかもしれない)


  • id:you1982
    ありがとうございます。

    実は省略しましたが、実際の状況ではテーブルBは一応、一意にソート可能なんです。

    とか言いつつ、実はそうでもなかったりもして設計からやり直すべきというのは重々、承知なのですが、いろいろコトの経緯や互換性という問題がありまして(苦笑)。
  • id:rikuzai
    >実際の状況ではテーブルBは一応、一意にソート可能なんです。

    どういった方法で一意にソートできているのでしょうか?
    テーブルAも一意にソート可ならば、そをキーにすればいいだけですし。
    正直そこが肝のような気がします…。


    ちなみにAccessの話ということなら、
    Accessはデータの並び順を記録しませんから、
    なんらかのキーがなかったらソートできないはずなんですが。
  • id:you1982
    テーブルBには、上記の他にいくつかフィールド(たとえばデータ入力日時みたいなもの)がありまして、それでソートすればテーブルBのソート順が毎回変わる、ということは「実用的には心配しないで良い状況」となっています。

    テーブルAの方も同様にソート可能なテーブルです。
  • id:rikuzai
    了解です。
    ではその「いくつかのフィールド」をキーにすればいいと思いますよ。
    複数あるなら連結してキーにするだけです。
    実際のSQL文が必要な場合は、具体的に「いくつかのフィールド」を提示された方が良いかと。
  • id:you1982
    たびたびありがとうございます。

    テーブルAの方にはあくまでも「行番号」しか記録されていないのですが、大丈夫でしょうか?

    例としては、テーブルBには「入力日時」というキーになり得るフィールドがあると考えてください。

    テーブルAに記載されているのはあくまでも、『当該顧客に対するテーブルBのレコードを「入力日時」でソートしたときに何行目のレコードが対応するか』ということだけです。

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

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

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

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