MSAceess テーブル結合でメモリエラー

このQ&Aのポイント
  • Windows XP, MS Access 2007でテーブル結合を行う際にメモリエラーが発生しています。
  • 結合するテーブル数が多すぎるため、レポートの表示が遅くなり、最後のページを開くとメモリ不足のエラーが出力されます。
  • OSの限界4GBに対して結合するテーブル数が大きすぎるため、効率的な方法を模索しています。
回答を見る
  • ベストアンサー

MSAceess テーブル結合でメモリエラー

Windows XP, MS Access 2007です。 レコード件数700件程度のテーブルTBLに以下のようなカラムがあります。 ID(主キー),NAME,REF_ID1, REF_ID2, REF_ID3,...., REF_ID10 NAMEは当該IDに紐づく名前であり、 REF_ID1~REF_ID10は、当該レコードと関連するレコードのIDを記載したものです。 これをレポート出力する際に、 関連レコードはIDではなく名前を出力したく 以下のようにクエリを作成しました。 SELECT TBL.ID, TBL.NAME, TBL1.NAME AS REF_NAME1, ...., TBL10.NAME AS REF_NAME10 FROM TBL, TBL AS TBL1, TBL AS TBL2, ..., TBL AS TBL10 WHERE TBL.REF_ID1 = TBL1.ID AND ... AND TBL.REF_ID10; しかし、この方法だと結合するテーブル数が多くなるためか、 レポートの表示が非常に遅く、かつ、レポートの最後のページを開こうとすると メモリ不足とのメッセージボックスが出力され、エラー終了してしまいました。 メモリはOSの限界4GBまで積んでいるため、 結合するテーブル数が多すぎるのが問題なのだと思いますが、 どのような方法がよいのでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8519/19366)
回答No.2

>結合するテーブル数が多すぎるのが問題なのだと思いますが、 >どのような方法がよいのでしょうか。 テーブル結合を、INNER JOINかLEFT JOINにする。 現状では「全部のテーブルが無条件結合」されるので、内部的に「総当りですべての組み合わせ」が内部的に作られてから、WHEREに一致しないレコードが除外されるので、たぶん、4GBのメモリがあっても足りないだろうと思われます。 「総当りですべての組み合わせを作った場合のレコード数」は「すべてのテーブルのレコード数を掛け算した数」です。 例えば、700レコードある基本のTBLに、50レコードあるテーブルを無条件に結合すると、内部的に700×50=35000レコードのデータが生成されます。 もし、主テーブルが700レコード、各サブテーブルが100レコードあれば、主のTBLにTBL1~TBL10を無条件結合すると、700×100×100×100×100×100×100×100×100×100×100=70000000000000000000000レコード生成されます。 1レコードに200バイト使用すると仮定すると、14000000000000000000000000バイト必要です。 自分が、どんだけ無謀な事をしようとしているか、理解した方が良いです。

palayo
質問者

お礼

LEFT JOINで結合条件を指定したところ、一瞬で終わりました。 ありがとうございました。

その他の回答 (5)

  • chie65535
  • ベストアンサー率43% (8519/19366)
回答No.6

追記。 ANo.4のクエリを 主TBL:700レコード 副TBL1~10:100レコード の11個のテーブルで結合してみたが、まったく問題なく動作した。 動作環境は、あえて WinXP Pro SP3 Access97 メモリ768MB CPU Celeron CPU 2.5GHz というチープな環境にしてみたが、まったく問題が無かった。

回答No.5

内部結合を使えばどうでしょうか。 SELECT TBL.ID, TBL.NAME, TBL_1.NAME, TBL_2.NAME, TBL_3.NAME, TBL_4.NAME, TBL_5.NAME, TBL_6.NAME, TBL_7.NAME, TBL_8.NAME, TBL_9.NAME, TBL_10.NAME FROM (((((((((TBL INNER JOIN TBL AS TBL_1 ON TBL.REF_ID1 = TBL_1.ID) INNER JOIN TBL AS TBL_2 ON TBL.REF_ID2 = TBL_2.ID) INNER JOIN TBL AS TBL_3 ON TBL.REF_ID3 = TBL_3.ID) INNER JOIN TBL AS TBL_4 ON TBL.REF_ID4 = TBL_4.ID) INNER JOIN TBL AS TBL_5 ON TBL.REF_ID5 = TBL_5.ID) INNER JOIN TBL AS TBL_6 ON TBL.REF_ID6 = TBL_6.ID) INNER JOIN TBL AS TBL_7 ON TBL.REF_ID7 = TBL_7.ID) INNER JOIN TBL AS TBL_8 ON TBL.REF_ID8 = TBL_8.ID) INNER JOIN TBL AS TBL_9 ON TBL.REF_ID9 = TBL_9.ID) INNER JOIN TBL AS TBL_10 ON TBL.REF_ID10 = TBL_10.ID; 試してないので、改善できるかどうかは不明です。 これで改善できないようなら、クエリを使わずに、レポートのレコードソースは TBL にして、 名前のテキストボックスをコンボボックスにして表示させるようにしたらどうでしょうか。 コンボボックスの設定は、 コントロールソース REF_ID1 値集合ソース TBL 連結列 1 列数 2 列幅 0cm 以下、コントロールソースのみ変更して、他のそのままの設定のコンボボックスを REF_ID10 まで作成します。

  • chie65535
  • ベストアンサー率43% (8519/19366)
回答No.4

具体的には、以下のようなクエリになるであろう。 SELECT TBL.ID, TBL.NAME, TBL1.NAME AS REF_NAME1, TBL2.NAME AS REF_NAME2, TBL3.NAME AS REF_NAME3, TBL4.NAME AS REF_NAME4, TBL5.NAME AS REF_NAME5, TBL6.NAME AS REF_NAME6, TBL7.NAME AS REF_NAME7, TBL8.NAME AS REF_NAME8, TBL9.NAME AS REF_NAME9, TBL10.NAME AS REF_NAME10 FROM (((((((((TBL INNER JOIN TBL1 ON TBL.REF_ID1 = TBL1.ID) INNER JOIN TBL2 ON TBL.REF_ID2 = TBL2.ID) INNER JOIN TBL3 ON TBL.REF_ID3 = TBL3.ID) INNER JOIN TBL4 ON TBL.REF_ID4 = TBL4.ID) INNER JOIN TBL5 ON TBL.REF_ID5 = TBL5.ID) INNER JOIN TBL6 ON TBL.REF_ID6 = TBL6.ID) INNER JOIN TBL7 ON TBL.REF_ID7 = TBL7.ID) INNER JOIN TBL8 ON TBL.REF_ID8 = TBL8.ID) INNER JOIN TBL9 ON TBL.REF_ID9 = TBL9.ID) INNER JOIN TBL10 ON TBL.REF_ID10 = TBL10.ID;

  • lv4u
  • ベストアンサー率27% (1862/6715)
回答No.3

>>それはそうだと思うので、どうすれば可能なのかを教えてください。 一般的には、いくつかの中間テーブルにいくつかのテーブルの結合結果を収容する処理を行います。 そうして、中間テーブルどうしを結合する処理にすれば、最終結果を得るときの結合テーブル数を減らすことが可能となります。

  • lv4u
  • ベストアンサー率27% (1862/6715)
回答No.1

>>結合するテーブル数が多すぎるのが問題なのだと思いますが、 どのような方法がよいのでしょうか。 結合するテーブル数を少なくするように工夫するのがいいと思います。

palayo
質問者

お礼

それはそうだと思うので、どうすれば可能なのかを教えてください。

関連するQ&A

  • テーブル結合

    度々お世話になっています。 Mysqlのテーブル結合したいと思ってます。 テーブル構成は以下のとおりですのでご参照ください。 ■テーブルA id | name 1 | bind 2 | samba 3 | apache ■テーブルB id | detail 3 | test 3 | test 1 | test ■結合結果 id | count 1 | 1 2 | 0 3 | 2 テーブルA,Bはidコラムで紐づいています。 この際、テーブルBのidごとにレコード数を出力したいのですが、 どういったSQLを流せば良いでしょうか。 ご教示願います。

    • ベストアンサー
    • MySQL
  • 結合で重複のエラーが出る

    mysql5.1.33を使用しています。 次のような構成で、 テーブル「tbl1s」 id int(11) テーブル「tbl2s」 id int(11) テーブル「tbl1s_tbl2s」 id int(11) tbl1_id int(11) tbl1sの外部キー tbl2_id int(11) tbl2sの外部キー テーブル「tbl2sbelongs」 id int(11) tbl2_id int(11) tbl2sの外部キー count int(11) テーブル「tbl1s」 +------+ |  id  | +------+ |  1  | +------+ |  2  | +------+ |  3  | +------+ テーブル「tbl2s」 +------+ |  id  | +------+ |  1  | +------+ |  2  | +------+ |  3  | +------+ テーブル「tbl1s_tbl2s」 +------+-------+-------+ |  id  | tbl1_id | tbl2_id | +------+-------+-------+ |  1  | 1    | 1   | +------+-------+------+ |  2  | 1    | 2   | +------+-------+------+ |  3  | 3    | 3   | +------+-------+------+ テーブル「tbl2sbelongs」 +------+-------+-------+ |  id  | tbl2_id | count | +------+-------+-------+ |  1  | 1    | 3   | +------+-------+------+ |  2  | 2    | 10  | +------+-------+------+ |  3  | 3    | 15  | +------+-------+------+ SELECT * FROM `tbl1s_tbl2s` AS `Tbl1sTbl2` INNER JOIN (SELECT *, sum(Tbl2sbelong.`count`) as sum FROM `tbl2s` AS `Tbl2` INNER JOIN `tbl2sbelongs` AS `Tbl2sbelong` ON (`Tbl2`.`id`=`Tbl2sbelong`.`tbl2_id`) WHERE 1 = 1 GROUP BY `Tbl2`.`id` ) AS `SUB` ON (`Tbl1sTbl2`.`tbl2_id`=`SUB`.`id`) WHERE 1 = 1 GROUP BY `tbl1_id` を実行すると、 「SQL Error: 1060: Duplicate column name 'id' 」 というエラーが出てしまいます・・・ おそらくカラムのidが結合の中で重複しているという内容だと思うのですが、 3つもテーブルが絡んでくるとどれのidがというのが分からないのですが、 これは何が原因なのでしょうか? ちなみにサブクエリの SELECT *, sum(Tbl2sbelong.`count`) as sum FROM `tbl2s` AS `Tbl2` INNER JOIN `tbl2sbelongs` AS `Tbl2sbelong` ON (`Tbl2`.`id`=`Tbl2sbelong`.`tbl2_id`) WHERE 1 = 1 GROUP BY `Tbl2`.`id` この段階までは実行できます。 最終的には、「tbl2sbelongs」テーブルの「count」の値によって、「tbl1s」を降順に並べ替えたいと思っています。 この例だと テーブル「tbl1s」 +------+ |  id  | +------+ |  3  |count = tbl2_id「3」の15 = 15 +------+ |  1  |count = tbl2_id「1」の3 + tbl2_id「2」の10 = 13 +------+ |  2  |count = 0 +------+

    • ベストアンサー
    • MySQL
  • テーブルを結合

    テーブルの結合に関して質問します。 ネットなどでinner joinを使った複数のテーブル結合が参考として 書いてあったのですが(3つまで), 4つテーブルを結合する事は 出来るのでしょうか? A,B,CテーブルにはID,NAMEがあります。 DテーブルにはA,B,CテーブルのIDがあります。 参考サイトを見て3つのテーブルを結合するSQLが以下になります。 SELECT a.name, b.name, c.name FROM a INNER JOIN (b INNER JOIN c ON b.id = c.id) ON a.id = c.id よろしければアドバイスお願いします。

  • 2つのテーブル結合

    Oracle10g使用しています。 テーブルAとテーブルBを結合させてデータを取得したいと思っています。 [テーブルA] ID name 1 A 2 B 3 C 4 D [テーブルB] ID SEQ VALUE 1 1 111 2 1 222 2 2 333 3 1 444 4 1 555 4 2 666 4 3 777 テーブルAのキーは[ID]、テーブルBのキーは[ID,SEQ]です。 この二つを連結して以下のように出力したいと思っています。 ID SEQ NAME VALUE 1 1 A 111 2 2 B 333 3 1 C 444 4 3 D 777 テーブルBのデータは同じIDのうち最大のSEQのものを取得したいのですが よいSQLが思いつきません。 よい方法があればご教授ください。 よろしくお願いいたします。

  • テーブル結合、JOINについて

    こんにちは。教えてください。 テーブルが3つあります。 これらを、条件にそって結合させたいと思っています。 TBL1 ID、NO TBL2 ID、ID名称 TBL3 NO、CD、NO名称 条件は、TBL1を全件表示し、TBL1のIDと等しいTBL2のID名称を 取得、TBL1のNOと等しいTBL3のNO名称を取得します。 ここまでは、うまくいくのですが、追加で条件があり、 TBL3については、CDが'0'の物のみを対象とします。 結果  ID、ID名称、NO、NO名称 となるようにしたいのですが・・・・ よろしくお願いします。

  • 結合テーブルクエリPrimaryKey取得について

    自己解決できず、どなたかお助けくださいませ。 環境:OS/Win7 ACCESS2010 やりたいことは、結合テーブルのクエリからPrimaryKeyを取得したいのです。 次の2つのテーブルと2つのフィールドを作成したとします。 Tbl_a.Fld_ID / Tbl_a.Fld_Name Tbl_b.Fld.ID / Tbl_b.Fld_Sex ※どちらも Fld_ID フィールド を PrimaryKey 名でINDEX設定します。 ACCESSに次のクエリを作成したとします。 SELECT Tbl_a.Fld_ID, Tbl_a.Fld_Name, Tbl_b.Sex FROM Tbl_a INNER JOIN Tbl_b ON Tbl_a.ID = Tbl_b.ID クエリ名:Q_AandB 次のVBAを作成したとします。 ※引数 VR には10万件の2次元配列 0:ID 1:氏名 2:性別 が入っている Public Sub UpdateExe(Byval VR As Variant) Dim DB As DAO.Database: Set DB = CurrentDB Dim RS As DAO.Recordset: Set RS = DB.OpenRecordset("Q_AandB") Dim Z As Long With RS For Z = 0 To UBound(VR) .Index = "PrimaryKey" ← ここでエラーが出ます。 .Seek "=", VR(Z,1) IF .NoMatch Then .AddNew !Fld_ID = VR(Z,0) 'ID !Fld_Name = VR(Z,1) '氏名 !Fld_Sex = VR(Z,2) '性別 .Update Else .Edit !Fld_ID = VR(Z,0) 'ID !Fld_Name = VR(Z,1) '氏名 !Fld_Sex = VR(Z,2) '性別 .Update End If Next Z .RS.Close End With Set RS = Nothing DB.Close: Set DB = Nothing End Sub これを実行すると、「実行エラー'3251': この操作は、このタイプのオブジェクトには 実行できません。」 とのエラーで弾かれてしまいました。 結合テーブルでのプライマリキーの取得がわからず困っております。 以上、何卒よろしくお願い申し上げます。

  • テーブルの結合について

    親テーブルに対して子テーブルが複数あるときの結合方法がわかりません。 テーブル2、3はそれぞれマスタテーブルの値を格納しています。 具体的には4つのテーブルを結合しテーブル1のname項目、テーブル2のtest項目、area_id、pref_idで検索をしたいです。 right joinで結合してみましたが、テーブル3、4でテーブル2のtest_idを2回参照するのでエラーがでてから先に進めない状況です。 他の回答を読んだのですができなかったので質問させてください。 お分かりの方教えてください。 よろしくお願いいたします。 [teble1] ID | name 1 佐々木 2 鈴木 3 田中 [teble2] test_id | ID(table1の値) | test 1 1       テスト1 2 1       テスト2 3 2       テスト3 [teble3] test_id | area_id 1    1 1    4 2    3 [teble4] test_id | pref_id 1    1 2    2 2    5 3    2 バージョンは4.0.27です。

    • ベストアンサー
    • MySQL
  • 他のデータベースとのテーブル結合

    いつもお世話になっております。 VB.netでwindowsアプリケーションの作成しているところです。 SQLサーバーのテーブルを参照していますが、テーブルの結合は同じデータベース内にないと結合できないのでしょうか? 'SQL接続処理 Dim strConn As String = "Password='';User ID=sa;Initial Catalog=test;Data Source=server1" と、testというデータベースがありその中に幾つかテーブルがあります。 このtestデータベースにないテーブルが必要になり、aaaデータベース内の テーブルを結合しようとしたのですが、出来ません。 Catalog=test,aaaとやってみたり、SELECT * FROM tbl1,aaa.tbl2などとしてみましたが、遠いようです。 SQLのクエリを使って、テーブルの追加をすると同じデータベース内のテーブルしか出てこないので、出来ないのかなと思っていますがどうでしょうか? わかる方がいましたら教えてください。

  • テーブルのOR外部結合2

    テーブル内容 TBL1 T1_ID T1_NM 100  T1_1 101  T1_2 102  T1_3 103  T1_4 ---------- TBL2 T1_ID T2_ID T2_NM 100  100  T2_1 101  101  T2_2 101  102  T2_3 102  103  T2_4 ---------- TBL3 T3_ID T3_TYPE T3_NM 100  T1    T3_1 100  T2    T3_2 101  T1    T3_3 101  T2    T3_4 102  T1    T3_5 102  T2    T3_6 ---------- 要求出力結果 T1_NM  T2_NM  T3_NM T1_1          T3_1 T1_1   T2_1    T3_2 T1_2          T3_3        T1_2   T2_2    T3_4 T1_2   T2_3    T3_5 T1_3          T3_6 T1_3   T2_4 T1_4 以上のデータ内容で要求出力結果を得たいです。 各テーブルの結合条件としては (T1.T1_ID = T2.T2_ID)(+) AND ( (T1.T1_ID = (T3.T3_ID AND (T3.T3_TYPE = 'T1')(+)) OR (T2.T2_ID = (T3.T3_ID AND (T3.T3_TYPE = 'T2')(+)) ) となります。 もちろんこのままだと外部結合の中にORがあるのでエラーとなります。 UNIONを使用せずに実現できますでしょうか?

  • 2つのテーブルを結合する条件

    現在、MySQLを使用しており2つのテーブルの結合条件がわからないので教えてください。 name_masterとmeiboの2つのテーブルがあります。 meiboとname_masterを結合させてname_idとname_id2が日本語に置き換わった状態で 取得させたいと思っています。どのようにwhere句の条件を作成すればよいでしょうか。 取得する項目のイメージとしては以下の3つが取得できるようにしたいです。 「meibo.no, meibo.name_idの日本語, meibo.name_id2の日本語」 【name_masterテーブル】 id name 1  ポチ 2  タマ 3  ミケ 4  ハチ 5  タロウ 【meiboテーブル】 no  name_id  name_id2 1    3     1 2    4     2 3    5     3

    • ベストアンサー
    • MySQL