質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

Q&A

解決済

2回答

3943閲覧

クエリ間で互いの片方にしかないデータも抽出する+特定のフィールドの内容をフィールド名に変え、数を返す

ma2_ra

総合スコア16

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

0グッド

0クリップ

投稿2018/06/12 12:58

編集2018/06/12 13:12

二つのクエリ(1,2)があり、ここから得たい結果がクエリ3です。
ポイントは二つあります。

1)クエリ1とクエリ2に共通のフィールドは「name」ですが、
これによって結合させつつ、一致しないデータ(C,D,E)も抽出したい。
※nameの種類は固定ではありません
2)クエリにある「place」の内容はa,bの2種類だけに抽出してあり、
これをplace_a、place_bというフィールドにし、1または0の数で得たい

クエリ1
name|cost
A|2000
B|3000
C|5000

クエリ2
name|place|number
A|a|001
B|a|002
B|b|002
D|b|003
E|a|004

クエリ3
name|cost|place_a|place_b|number
A|2000|1|0|001
B|3000|1|1|002
C|5000|0|0|-
D|-|0|1|0|003
E|-|1|0|004

実はこのあと、最終的にはnameとnumberでグループ化し、
numberで他のクエリと結合する必要があります。

互いに片方にしかないデータも抽出、となるとユニオンクエリでつないで
グループ化してカウント?合計?かな、とは思っているのですが、
SQLの記述がよくわかりません。

初心者でもわかりやすいシンプルな方法をお授けください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

見辛いので「表の挿入」で整形
#クエリ1

namecost
A2000
B3000
C5000

#クエリ2

nameplacenumber
Aa001
Ba002
Bb002
Db003
Ea004

#クエリ3

namecostplace_aplace_bnumber
A200010001
B300011002
C500000-
D-01003
E-10004

本題

片側にしかないものも全て結合する事を**「全部外部結合」(full outer join)と言います。
accessではサポートされていません。
サポートされていない場合にどうするかと言えば、unionしたものを基準にそれぞれ
「外部結合」(outer join)**します。

先ずはunionクエリーを作成します。
[クエリ0]

SQL

1SELECT name FROM クエリ1 2UNION select name from クエリ2 3;

次に[クエリ2]を元にplace_a,place_bを生成するクエリーを作り保存します。
[クエリ2_1]

SQL

1SELECT name 2 , Max(IIf([place]='a',1,0)) AS place_a 3 , Max(IIf([place]='b',1,0)) AS place_b 4 , number 5FROM クエリ2 6GROUP BY name, number 7;

クエリ0を元にクエリ1とクエリ2_1を外部結合して、整形します。
[クエリ3]

SQL

1SELECT クエリ0.name 2 , クエリ1.cost 3 , クエリ2_1.place_a 4 , クエリ2_1.place_b 5 , クエリ2_1.number 6FROM (クエリ0 LEFT JOIN クエリ1 7 ON クエリ0.name = クエリ1.name 8 ) LEFT JOIN クエリ2_1 9 ON クエリ0.name = クエリ2_1.name 10;

※nameは予約語なので項目名等で使用するのお勧めしません。

投稿2018/06/12 14:20

編集2018/06/14 07:25
sazi

総合スコア25083

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ma2_ra

2018/06/14 07:14

ありがとうございます。 質問に用いたのはサンプルで、フィールド名はダミー、実際は予約語とかぶりません。 ただ、例示したものを同じクエリを用意し、ご教示いただいたSQLを記述してみたのですが、 クエリ3を実行しようとすると、「メモ型またはOLEオブジェクト型(クエリ0.[name]=クエリ1.[name])のフィールドを結合することはできません。」と出てしまいます・・・。
sazi

2018/06/14 07:19

元々のクエリ1とクエリ2のnameフィールドの型は何ですか?
ma2_ra

2018/06/14 07:29

クエリのnemeフィールドの型って、プロパティの書式ですか?文字書式ですか? 書式は空白で何も選べません。文字書式は「テキスト形式」にしました。 クエリのもとになっているテーブルはいずれも長テキスト型です。
ma2_ra

2018/06/14 12:38

短いテキストでうまくできました。 実際のデータも短テキストでおさまりそうなので試してみます。
ma2_ra

2018/06/26 02:40

実際にはうまくいかない点が一つあったのですが、これは別課題にしたいと思います。 本課題は解決しました!ありがとうございます。
guest

0

まずクエリBのplaceを横持ちに変換するのはこう書きます。

sql

1select 2 [name], 3 count(case place when 'a' then 1 end) as place_a, 4 count(case place when 'b' then 1 end) as place_b, 5 [number] 6from 7 b 8group by [name], [number]

これをクエリAと外部結合するのでこうなります。

sql

1select 2 a.[name], a.cost, b_ex.place_a, b_ex.place_b, b_ex.[number] 3from 4 a 5 full outer join ( 6 select 7 [name], 8 count(case place when 'a' then 1 end) as place_a, 9 count(case place when 'b' then 1 end) as place_b, 10 [number] 11 from 12 b 13 group by [name], [number] 14 ) b_ex on a.[name] = b_ex.[name]

投稿2018/06/12 14:11

編集2018/06/12 14:13
yuba

総合スコア5568

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sazi

2018/06/12 14:42 編集

full joinが使えるようになったのかと思ったけど、よく見るとcaseとかも使われているので、違いますね。 accessですよ。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問