プロが教えるわが家の防犯対策術!

AccessのSQLで外部結合を複数使うと
SQLがエラーになります。
クエリで確認してエラーにならない様につくってみましたが、意図する事をやろうとするとエラーになります。
どこが悪いか教えていただけませんか?おそらくSQLサーバーでは余裕で通るSQLだと思うのですが。。。
SQL = SELECT * FROM T1
LEFT JOIN T2 ON T1.A = T2.A
LEFT JOIN T3 ON T1.B = T3.B
LEFT JOIN T4 ON T1.C = T4.C
AND T4.D = iNum
WHERE T1.E = 'iNum'
やりたいのはT1を基準にT2,T3,T4からデータを引っ張ってきたい。その条件としてT4から引っ張ってくるのは
T4.DがiNumである事、基準となるT1のT1.EがiNumである事です。
Accessでは"AND T4.D = iNum"がだめで、
WHERE区に書くと外部結合にもかかわらずT4.D = iNumのデータしか抽出されなくなる。(T1.C = T4.CのデータがT4.D = iNumでなくてもT1のデータが抽出されなくてはならない。)
さらに
SQL = SELECT * FROM ((T1
LEFT JOIN T2 ON T1.A = T2.A)
LEFT JOIN T3 ON T1.B = T3.B)
LEFT JOIN T4 ON T1.C = T4.C
AND T4.D = iNum
WHERE T1.E = 'iNum'
こんな括弧が必要になってくる。
これだとT1とT2を外部結合した結果をT3と外部結合して
さらにその結果をT4と外部結合しているという意味あいになってしまって、意図が違うのですが。。
結果は同じなのでAccessに譲ってやってもいいのですが
前者はT1で抽出されなければならないデータが抽出されないので困ります。
よろしくお願いいたします。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

失礼、記述ミスしてました。


書きたかったのは、以下のSQLです。

SELECT * FROM ((T1
LEFT JOIN T2 ON (T1.A=T2.A))
LEFT JOIN T3 ON (T1.B=T3.B))
LEFT JOIN T4 ON (T1.C=T4.C AND T1.E=T4.E)
WHERE T1.E = 'iNum'
    • good
    • 0
この回答へのお礼

お返事おそくなって申し訳ありません。
回答いただいたSQLですが、
T4にEという項目はなく、
T1.E=T4.Eはできません。
No1の回答で私のつくったSQLをみていただいたら
何がしたかったのかがわかっていただけると思います。
ありがとうございました。

お礼日時:2005/12/13 08:59

たぶん、こんな感じで良いないかと。



SELECT * FROM ((T1
LEFT JOIN T2 ON (T1.A=T2.A))
LEFT JOIN T3 ON (T1.B=T3.B))
LEFT JOIN T4 ON (T1.C=T4.C AND T1.D=T4.D)
WHERE T1.E = 'iNum'

気になる部分だけ、コメントを書きますが・・

>これだとT1とT2を外部結合した結果をT3と外部結合して
>さらにその結果をT4と外部結合しているという意味あいになってしまって、
>意図が違うのですが。。

T1を基準として、結合条件とするなら、外部結合は、どのような順番で行っても、
結果は変わりませんよ。(少なくとも、上記の条件であれば、同じハズ)
    • good
    • 0
この回答へのお礼

早速回答いただき、ありがとうございます。

せっかく回答いただいたのですが、

>LEFT JOIN T4 ON (T1.C=T4.C AND T1.D=T4.D)
>WHERE T1.E = 'iNum'

T1には"D"という項目はなく、
T4のなかのT4.D = 'iNum' を満たすレコードのみ
CというKeyでT1と外部結合させたいのです。

今これを書いていて思いついたのですが、

SELECT * FROM ((T1
LEFT JOIN T2 ON (T1.A=T2.A))
LEFT JOIN T3 ON (T1.B=T3.B))
LEFT JOIN (SELECT * FROM T4 WHERE T4.D ='iNum') AS T5 ON T1.C=T5.C
WHERE T1.E = 'iNum'

でいけました~。
他に何かご存知の方ありましたら
教えてください。
よろしくお願いいたします。

お礼日時:2005/11/28 12:21

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

関連するカテゴリからQ&Aを探す

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q【Access】外部結合を行う前に抽出条件をつけたいのですが。。。

こんにちは。困っているので助けて頂きたいです。

Windows2000+Accessでシステムを組んでいます。
多分、とても基礎的な事だと思うのですが、行き詰まっております。

テーブル2つを結合させようとしています。

<データテーブル>
区分 金額 地域名
1   3000 1
1   3000 1
1   3000 3
2   3000 3
2   3000 1

<マスタ>
地域   地域名
1     大阪
2     京都
3     福岡

この2つのテーブルから、
マスタのデータ全部と、
データテーブルの中で区分が「1」のデータだけを結合させて、
金額を合計したいのです。

望んでいる結果は
地域   地域名  金額
1     大阪   6000
2     京都   0
3     福岡   3000

です。

クエリを二つ作成すればできるのでしょうが、諸処の事情で、どうしても一つのクエリでやってしまいたいのです。

拙い説明で申し訳ないのですが、
どなたかお知恵をお貸し頂きたく、宜しくお願い致します。

こんにちは。困っているので助けて頂きたいです。

Windows2000+Accessでシステムを組んでいます。
多分、とても基礎的な事だと思うのですが、行き詰まっております。

テーブル2つを結合させようとしています。

<データテーブル>
区分 金額 地域名
1   3000 1
1   3000 1
1   3000 3
2   3000 3
2   3000 1

<マスタ>
地域   地域名
1     大阪
2     京都
3     福岡

この2つのテーブルから、
マスタのデータ全部と、
データテーブルの中で...続きを読む

Aベストアンサー

 
※ エイリアスは適宜変更すること。

SELECT
マスタ.地域,
マスタ.地域名,
Sum(nz([金額明細])) AS 金額
FROM
マスタ
LEFT JOIN
[SELECT
区分,
金額 As 金額明細,
地域名
FROM
データテーブル
WHERE
区分 = 1]. qry
ON
マスタ.地域 = qry.地域名
GROUP BY
マスタ.地域, マスタ.地域名;
 

QACCESSで空白のデーターをクエリで判定/識別する方法を教えてくださ

ACCESSで空白のデーターをクエリで判定/識別する方法を教えてください。
EXCELでは空白を""で判定/識別表していますがACCESSではどうなるのでしょうか。

下の例はフィールドに試験番号があればその番号を、空白なら”欠席”と表示しようとしています。
IIf(([試験番号]="空白の場合何を入れる?"),[試験番号],"欠席")

Aベストアンサー

もうひとつの書き方は
式1: IIf([試験番号] Is Not Null,[試験番号],"欠席")
第2、第3引数の、質問の順序にあわせるとこうなる。

QACCESS IIF関数 複数条件の設定について

 選択クエリにおいて、あるフィールド「 X」 のレコード数値が
 
  0<[X]<=50   であれば A 
  50<[X]<=100  であれば B 
  100<[X]<=150  であれば C

 と表記させるフィールド「Y」を追加したいと考えています。
 この場合、Yのフィールド設定で指定する数式についてご教授願います。

 一応、
  IIf(0<[X]<=50,"A","") Or IIf(50<[X]<=100,"B","") Or IIf(100<[X]<=150,"C","")

  としましたが、実行すると、Yの列がすべて「-1」と表記されてしまいます。

 何卒よろしくお願いいたします。

Aベストアンサー

a)IIF関数で対応する場合:
 IIF関数の第2引数または第3引数に、IIF関数を入れ子とする必要があります。

式: IIF([X]<=0, "", IIF([X]<=50, "A", IIF([X]<=100, "B", IIF([X]<=150, "C", ""))))


b)別の組込関数を使用する場合:
 IIF関数は二択ですので入れ子にする必要がありますが、Accessのクエリで
 使用できる、似た機能の関数に、Switch関数というものもあります。
 これであれば、入れ子にする必要がなくなります。
 (詳しくは、Accessのヘルプを参照下さい)

式: Switch([X]<=0, "", [X]<=50, "A", [X]<=100, "B", [X]<=150, "C", True, "")


なお、数学あるいは一般生活では確かに「0<[X]<=50」という表記をしますが、
Accessの関数などではこれだと正しい結果が得られません。
正しく認識させるためには、等号・不等号を挟んだ式は、「左辺」と「右辺」の
2つの要素からなる形にする必要があります。
(「0<[X]<=50」は「[X]>0 And [X]>=50」と分割してやる、と)

但し、今回のご質問のような『連続した範囲』であれば、前(左)で既出となる
式の要素で「[X]<=0」が「真(=-1)」とならなかった時点で、「[X]>0」が保証
されますので、上記のように、「[X]>0」を省略して「[X]<=50」だけを条件として
指定すればOk、ということになります。
(「0<[X]<=50」の次が「80<[X]<120」などのように、「50~80」が欠けた
 場合は、省略ができない、と)


【参考】
「0<[X]<=50」は、このままだと「0 < ([X]<=50)」という式と解釈されます。
この場合、「[X]<=50」は、「真(=-1)」か「偽(=0)」か「Null」のいずれかに
なります。
何にせよ、「0<[X]<=50」全体として「正(=-1)」となることがないため、
ご質問の式では、IIF関数は常に第3引数に指定された値「""」を返す
ことになります。

この結果、式全体としては「"" Or "" Or ""」という形となり、「0かNull」
以外なので、「真(=-1)」という値が返された、ということです。

なお、Nullについては、以前、他の方の質問につけた回答も、併せて参考までに:
http://oshiete.goo.ne.jp/qa/4850675.html

a)IIF関数で対応する場合:
 IIF関数の第2引数または第3引数に、IIF関数を入れ子とする必要があります。

式: IIF([X]<=0, "", IIF([X]<=50, "A", IIF([X]<=100, "B", IIF([X]<=150, "C", ""))))


b)別の組込関数を使用する場合:
 IIF関数は二択ですので入れ子にする必要がありますが、Accessのクエリで
 使用できる、似た機能の関数に、Switch関数というものもあります。
 これであれば、入れ子にする必要がなくなります。
 (詳しくは、Accessのヘルプを参照下さい)

式: Switch([X]<=0, "", [X]<=50, "A"...続きを読む

Q複数のテーブルに対してのleft join

前回他の方が質問していますが、、、
T1、T2、T3、T4がありまして
T1が軸のテーブルです。
その場合

select T1.a,T2.b,T3.c
from T1,T2,T3 left join T4
on T1.x = T2.x
and T2.xx = T3.xx
and T2.xxx = T4.xxx
where T4.x is null

というふうなSQLを発行しようとしたのです。
しかし「onが無効」と怒られました。
ご存知の方教えてください。
HPなどご存知の方お願いいたします。

DB2/UDBです。

Aベストアンサー

DB2を使用したことが無いのでSQL一般論で回答します。

onは、T3とT4に対しての結合条件指定になっているのにに他のテーブルの結合条件を示しているのでエラーになっています。

from (((T1 inner join T2 on T1.x=T2.X)
inner join T3 on T2.XX = T3.XX)
left outer join T4 on T2.XXX = T4.XXX)
でいかがですか。
(質問からは、T1,T2,T3の結合条件が読み取れないので等結合としました。)

もしくは、whereで結合すればいいと思います。

QLEFT JOINが2つあるSQL文でANDの意味

■下記SQL文の意味を教えてください

SELECT a.*, b.being_name
FROM alive a
 LEFT JOIN being b ON a.hoge_id = b.id
 LEFT JOIN call c ON c.call_id = a.hoge_id
  AND f.hoge_id = 12
 WHERE f.hoge_id = 12 OR b.id = 12

※12の部分は動的に切り替わります

・LEFT JOINが2つあるので、3つのテーブルを結合しているのでしょうか?
・左テーブルは「alive a」で、この右側に2つのテーブルが結合している、という認識でよいでしょうか?

>SELECT フィールド名 FROM テーブル名 WHERE 条件式1 AND 条件式2
>「AND」は2つの条件式の論理積
・上記内容をネットで見かけたのですが、「AND」は、「WHERE」の前に来てもいいのでしょうか? それともこのSQLの「AND」は違う使い方をしているのでしょうか? 何か、LEFT JOINに関係しているのでしょうか?

■下記SQL文の意味を教えてください

SELECT a.*, b.being_name
FROM alive a
 LEFT JOIN being b ON a.hoge_id = b.id
 LEFT JOIN call c ON c.call_id = a.hoge_id
  AND f.hoge_id = 12
 WHERE f.hoge_id = 12 OR b.id = 12

※12の部分は動的に切り替わります

・LEFT JOINが2つあるので、3つのテーブルを結合しているのでしょうか?
・左テーブルは「alive a」で、この右側に2つのテーブルが結合している、という認識でよいでしょうか?

>SELECT フィールド名 FROM テーブル名 WHERE 条件式1 AND 条件式...続きを読む

Aベストアンサー

>・LEFT JOINが2つあるので、3つのテーブルを結合しているのでしょうか?
はいそうです。

>左テーブルは「alive a」で、この右側に2つのテーブルが結合している、という認識でよいでしょうか?
はいそうです。(alive→beingって言うような意味です。)

>・上記内容をネットで見かけたのですが、「AND」は、「WHERE」の前に来てもいいのでしょうか?
「AND]は「WHERE」にかかっているのではなく「LEFT 」の結合の条件となります。
SELECT a.*, b.being_name
FROM alive a
LEFT JOIN being b ON a.hoge_id = b.id
LEFT JOIN call c ON (c.call_id = a.hoge_id AND f.hoge_id = 12)
WHERE f.hoge_id = 12 OR b.id = 12

<<追記>>
このSQLにはfというテーブルが存在しないのでエラーとなります。

QAccessのRefresh・Requery・Repaintの違い

Requeryはもう一度ソースレコード(テーブル)を読み込むようです。このとき、テーブルの先頭レコードに移動してしまいます。
Refreshは最新のレコード(テーブル)を再表示するような気がします。レコードの移動は起こらない気がします。
Repaintは、VBAでキャプションなどを変更したとき使っています。
でも、よくわかっていません。
どんなときにどんなメソッドを使えばいいのでしょうか?
詳しい方、よろしくお願いいたします。

Aベストアンサー

たびたびすみません。
調べてたらこんなのがでてきました。
http://www.nurs.or.jp/~ppoy/access/access/acF007.html

参考URL:http://www.nurs.or.jp/~ppoy/access/access/acF007.html

QAccess2010 「演算子がありません」エラー

フォーム上に別フォームを開くボタンがあるのですが、クリックすると実行時エラーが表示されます。

実行時エラー 3075
クエリ式”コード IN(○○,××)の構文エラー 演算子がありません。

コードを数値型からテキスト型に変更したのが原因だと思います。
エラーが出ない方法を教えていただければ助かります。
よろしくお願いいたします。

Dim rst As Recordset
Dim strWhere As String

Set rst = Me.RecordsetClone
With rst
If .RecordCount = 0 Then
Beep
Exit Sub
End If
.MoveFirst
strWhere = ""
Do Until .EOF
strWhere = strWhere & IIf(Len(strWhere) > 0, ",", "") & !コード
.MoveNext
Loop
.Close
strWhere = "コード IN (" & strWhere & ")"
End With

DoCmd.OpenForm "フォーム", , , strWhere

フォーム上に別フォームを開くボタンがあるのですが、クリックすると実行時エラーが表示されます。

実行時エラー 3075
クエリ式”コード IN(○○,××)の構文エラー 演算子がありません。

コードを数値型からテキスト型に変更したのが原因だと思います。
エラーが出ない方法を教えていただければ助かります。
よろしくお願いいたします。

Dim rst As Recordset
Dim strWhere As String

Set rst = Me.RecordsetClone
With rst
If .RecordCount = 0 Then
Beep
Exit Sub
End If
...続きを読む

Aベストアンサー

補足をよんでいなかったので、In句の中身の使い道
がわかりませんでした。

コード IN(○○,××)

○○,××は、元フォームに表示されているレコードになりますので


ということならば、No3の方の回答の、

strWhere = ",'" & !コード & "'"



strWhere = strWhere & ",'" & !コード & "'"

にすればよろしいかと。

QInner join と Left joinの明確な違いは?

Inner join と Left joinの違いがよくわかりません。
教えてください。

Aベストアンサー

出てくる結果が違います。

テーブル1のフィールド1に、






が、

テーブル2のフィールド1に、






が入力されている場合、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 LEFT JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3               3
4               NULL
5               NULL
6               NULL
の6レコードが出力されますが、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 INNER JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3               3
の3レコードしか出力されません。

出てくる結果が違います。

テーブル1のフィールド1に、






が、

テーブル2のフィールド1に、






が入力されている場合、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 LEFT JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3           ...続きを読む

QAccess2007でSQLの複数列副問い合わせについて

VB2005+Access2007を使用しております
SQL文の複数列副問い合わせについて教えて下さい

検索をしても他のデータベースのものばかりヒットし、解決できません

SELECT *
FROM Uriage
WHERE
(Date, DateID) = (SELECT Date, DateID FROM Uriage WHERE NAME = 'cup')

これを実行すると
「メイン クエリの FROM 句の予約語 EXISTS を使用しないフィールド
を複数返すサブクエリを作成しました。サブクエリのSELECT ステート
メントを変更し、1 つのフィールドだけを指定してください。」
というエラーがでてしまいます。


形をかえ、

SELECT *
FROM Uriage
WHERE
Date = (SELECT Date FROM UriageList WHERE NAME = 'cup')
AND
DateID =(SELECT DateID FROM UriageList WHERE NAME = 'cup')

これを実行すると、
「このサブクエリでは 1 つのレコードしか返せません。」
というエラーがでてしまいます。

また、

SELECT *
FROM Uriage
WHERE
(Date) IN (SELECT Date FROM UriageList WHERE NAME = 'cup')
AND
(DateID) IN (SELECT DateID FROM UriageList WHERE NAME = 'cup')

を実行したところ、
エラーはでないものの、抽出結果が異なるものが出てきてしまいました。


これを解決するにはどのようにしたらよいのでしょうか?
よろしくお願いいたします。

なお、某知恵袋にも同様の質問をしてしまいましたが、
回答者様への回答や追加質問が出来ず、
こちらに再質問させて頂きました。申し訳ございません。

VB2005+Access2007を使用しております
SQL文の複数列副問い合わせについて教えて下さい

検索をしても他のデータベースのものばかりヒットし、解決できません

SELECT *
FROM Uriage
WHERE
(Date, DateID) = (SELECT Date, DateID FROM Uriage WHERE NAME = 'cup')

これを実行すると
「メイン クエリの FROM 句の予約語 EXISTS を使用しないフィールド
を複数返すサブクエリを作成しました。サブクエリのSELECT ステート
メントを変更し、1 つのフィールドだけを指定してください。」
というエ...続きを読む

Aベストアンサー

知恵袋にも回答しましたが、
INNER JOIN を使えばどうでしょうか。
副問い合わせより高速にできる可能性が大です。

SELECT Uriage.Date, Uriage.DateID
FROM
Uriage INNER JOIN UriageList
ON Uriage.Date = UriageList.Date AND Uriage.DateID = UriageList.DateID
WHERE UriageList.NAME = 'cup';

QアクセスVBAのMe!と[ ]

基本的なことですみません。

アクセスのイベントプロシージャで、Me!ってありますけど、これはどういう意味なんでしょうか?

また、Me!の後に、Me!.~~と書く場合と、Me!.[~~]と書く場合がありますが、どこが違うのでしょうか?

Aベストアンサー

>プロシージャ内で[]を使う場合は、そのフォーム外のオブジェクトを使う場合と考えてよろしいでしょうか?
別のオブジェクトを使う場合だけではありません。
Hensu = Me![Text1]のようにHensuという変数に自身のTest1の値を代入する場合のように。
[]で括られているのがオブジェクト名やコントロール名だよという事。
クエリの抽出条件に存在しない[?]とすれば?というコントロール等が参照できないので?というダイアログが表示されるように?というオブジェクトやコントロールは何?と聞いてくるように。
>フォーム内のオブジェクトの場合はあくまでMe!で良いのでしょうか
Forms.[フォーム名]![コントロール名]やForms![フォーム名]![コントロール名]が構文。
アクティブなフォームが自分自身ならForms![フォーム名]の変わりにMeでもOKですという事。

と言う解釈の方が良いと思います。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング