- ベストアンサー
Accessで異なる数を、複数のフィールドに結合
- Accessで複数のフィールドを結合する方法を教えてください。
- 条件により異なる数を指定したフィールド同士を結合する方法を知りたいです。
- テーブルAとテーブルBのフィールドを条件に基づいて結合したいのですが、可能でしょうか?
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
No5です。 「True」という文字列がBooleanで返す「True」とまぎわらしい、という ことであれば、 Function funcJudge(ByVal fP As Long, ByVal fQ As Long, ByVal fR As Long, ByVal fS As Long) As String '最初の条件 If fP = 0 And fQ >= 1 And fR = 2 And fS = fQ Then funcJudge = "同値" Exit Function End If '二番目の条件 If fP >= 1 And fQ >= 1 And fR = 1 And fS = fP Then funcJudge = "同値" Exit Function End If End Function のように「同値」でもかまいませんが。
その他の回答 (5)
- piroin654
- ベストアンサー率75% (692/917)
いろいろ想像を巡らしてみました。 理解の仕方が違っているかもしれませんが。 テーブル1とテーブル2の行が1対1で対応していると解釈し、 それぞれ同じレコード数あるというようにした場合。 条件の解釈を、 (フィールドp、フィールドq)=(0、n)のとき、(フィールドr、フィールドs)=(2、n)と同値とする は、 (フィールドp、フィールドq)=(0、n)かつ、(フィールドr、フィールドs)=(2、n)ならば、 真とする。 また、 (フィールドp、フィールドq)=(m、n)のとき、(フィールドr、フィールドs)=(1、m)と同値とする は、 (フィールドp、フィールドq)=(m、n)かつ、(フィールドr、フィールドs)=(1、m)ならば、 真とする。 と置き換えます。 そこで、次のコードを標準モジュールに貼り付け、保存してください。 Function funcJudge(ByVal fP As Long, ByVal fQ As Long, ByVal fR As Long, ByVal fS As Long) As String '最初の条件 If fP = 0 And fQ >= 1 And fR = 2 And fS = fQ Then funcJudge = "True" Exit Function End If '二番目の条件 If fP >= 1 And fQ >= 1 And fR = 1 And fS = fP Then funcJudge = "True" Exit Function End If End Function このコードは条件に合ったときのみ、"True"という文字列を返します。 本来は、関数の戻値をStringではなくBooleanでもいいのですが、 分かりやすくStringとしておきます。 次に、二つのテーブルを1対1で結びつけるオートナンバーを設定し、 それぞれそのフィールドをIDとします。主キーではありません。 クエリを以下のように設定します。 SELECT テーブル2.フィールドr, テーブル2.フィールドs, funcjudge([テーブル1]![フィールドp],[テーブル1]![フィールドq],[テーブル2]![フィールドr],[テーブル2]![フィールドs]) AS 判定 FROM テーブル1 INNER JOIN テーブル2 ON テーブル1.ID = テーブル2.ID; 上記のクエリには、二つの条件の一方に当てはまれば、「判定」という フィールドに、「True」と表示されます。 「True」と表示されたテーブル2のレコードが「特定したい」という データに相当するのではと思っているのですが、という解釈が一つです。どうでしょう。 もし、テーブル1とテーブル2のレコード数は同じではなく、 テーブル2はテーブル1よりも多い、あるいは反対の 場合は方法を変えなければなりませんが。
- 30246kiku
- ベストアンサー率73% (370/504)
提示された条件から > ※m、nは1以上の整数です > ・(フィールドp、フィールドq)=(0、n)のとき、(フィールドr、フィールドs)=(2、n)と同値とする SELECT * FROM TA INNER JOIN TB ON TA.q=TB.s WHERE TA.p=0 AND TA.q>=1 AND TB.r=2 > ・(フィールドp、フィールドq)=(m、n)のとき、(フィールドr、フィールドs)=(1、m)と同値とする SELECT * FROM TA INNER JOIN TB ON TA.p=TB.s WHERE TA.p>=1 AND TA.q>=1 AND TB.r=1 上記を UNION ALL を使って、 SELECT * FROM TA INNER JOIN TB ON TA.q=TB.s WHERE TA.p=0 AND TA.q>=1 AND TB.r=2 UNION ALL SELECT * FROM TA INNER JOIN TB ON TA.p=TB.s WHERE TA.p>=1 AND TA.q>=1 AND TB.r=1; もし、重複するものがあって排除するのなら UNION ALL を UNION に変更します。 また、違う書き方すれば SELECT * FROM TA, TB WHERE (TA.q=TB.s AND TA.p=0 AND TA.q>=1 AND TB.r=2) OR (TA.p=TB.s AND TA.p>=1 AND TA.q>=1 AND TB.r=1); になるかも・・・・ ※ 各処理性能はわかりません
お礼
30246kikuさん、ご回答ありがとうございました。 また、返事が遅れてしまって申し訳ありませんでした。見よう見まねでSQL構文を組んでおりまして…。 ユニオンクエリ、WHERE以下の複数条件の両方を組み、実行することができました。 今回、各データはIDで結合させているので、重複を排除する必要はありませんでした。 結果、ユニオンクエリは処理に1分以上を要するようで、数秒で済む複数条件の方を取ろうかと思っています。 質問の締め切りは、もうお一方が示されたVBAの処理を試みたあとで行う予定です。 ご協力いただき、本当に助かりました。感謝しております。 また何かあれば、よろしくお願いいたします。
- piroin654
- ベストアンサー率75% (692/917)
失礼しました。たとえば以下のようなテーブルが あるとして、 [テーブル1] フィールドp フィールドq 5 3 9 0 0 3 6 9 1 9 [テーブル2] フィールドr フィールドs 0 3 6 3 1 9 9 0 1 3 どのような結果が必要なのでしょうか。 「結合」、あるいは「つなげる」とは?
補足
度々ご回答ありがとうございます。 「結合」「つなげる」という言い方は、たとえば クエリのデザインビューで、テーブル同士のフィールドを結合線でつなげる、 というイメージをもとに使っていました。 しかし、今回「結合」したいのは、各テーブルのフィールド2つの組み合わせなのです。 (その後、テーブル2の別のフィールドtに登録されたデータを今回のクエリに表示させ、 別の選択クエリXで表示させる予定です。 このフィールドtには、別途抽出したいデータも混在しており、 初めに作った選択クエリXでは同時に抽出できなかったためです。 このフィールドtで、今回抽出したいデータを特定するためのデータは、 テーブル1のフィールドr、sにしか存在していません ) 以下に、ご提示いただいた表の内容を変えて説明いたします。 テーブル1、2の行ごとに、それぞれ対応しています。 これらが同値であるように設定したい (そして、テーブル2のフィールドtのデータを得たい) のです。 お力添え願えますでしょうか。 [テーブル1] フィールドp フィールドq 0 3 0 2 1 3 6 9 2 8 [テーブル2] フィールドr フィールドs 2 3 2 2 1 1 1 6 1 2
- piroin654
- ベストアンサー率75% (692/917)
すみません。やはり勘違い。フィールドの設定を間違えていました。 No1は引っ込めます。
- piroin654
- ベストアンサー率75% (692/917)
勘違いしていたらごめんです。 条件を元に、それぞれのテーブルからクエリを作成し、 それぞれのクエリをユニオンクエリで結合するということ でいいのでしょうかね。 SELECT IIf([テーブルA]![フィールドp]=0 And [テーブルA]![フィールドq]>=1,2,[テーブルA]![フィールドp]) AS PR, IIf([テーブルA]![フィールドp]=0 And [テーブルA]![フィールドq]>=1,[テーブルA]![フィールドq],[テーブルA]![フィールドq]) AS QS FROM テーブルA UNION SELECT IIf([テーブルB]![フィールドr]>=1 And [テーブルB]![フィールドs]>=1,1,[テーブルB]![フィールドr]) AS PR, IIf([テーブルB]![フィールドr]>=1 And [テーブルB]![フィールドs]>=1,[テーブルB]![フィールドr],[テーブルB]![フィールドs]) AS QS FROM テーブルB;
補足
ご回答ありがとうございます。 上記内容は取り消されたとのことですが、やりたいことについて補足します。 各テーブルでクエリを作成するとまでは考えていませんでした。 ユニオンクエリでなく、選択クエリで各テーブルを表示し、先の条件でつなげられればいいかな、と…。 (もしかしたら「結合」の使い方が間違っていたかもしれません)
お礼
返事が遅くなって申し訳ありません。 これ以上返事を遅らすのもどうかと思い、現在の進捗報告をお礼に代えさせていただきたいと思います。 「同値」を真偽の判定と読み替えて、VBAを使用する、とは目から鱗でした! また、ご推測の通り、以下の2点が当てはまります。 ・ テーブル1とテーブル2の行が1対1で対応しており、それぞれ同じレコード数ある。 ・ 「True」と表示されたテーブル2のレコードが「特定したい」というデータに相当する。 (判定の文字列は「True」「同値」いずれでも構いません。 Booleanで判定させる場合はVBAでの設定が必要、ということでしょうか。 Booleanでないといけない訳ではありませんが…) しかし、実際の各テーブルで対応するレコードは、同じ順序に並んでいるわけではないのです。 これには、双方のテーブルで各レコードに割り当てられているIDを結合させれば、解決できそうな気がします。 piroin654さんには多くアドバイスをいただきました。 (各テーブルのレコード数が等しくない場合の対策も知っておきたい、 などと言うと長引くので置いておきます) 今回長くお付き合いいただいた感謝の意を込めて、今回はBAとさせていただきます。 ありがとうございました。また何かあれば、よろしくお願いいたします。