こんにちは、ちょっと複雑なSQLの結合で困っています。
次のような名簿テーブルがあります。
ID, Name, IsMarried
1, 田中, True
2, 鈴木, True
3, 高橋, False
4, 中村, True
「IsMarried」は結婚しているかどうかを示しています。
そして、次のような属性テーブルがあります。
ID, ParentID, Type, Value
1, 1, 1, 55kg
2, 1, 2, 170cm
3, 1, 3, AB型
4, 2, 1, 52kg
5, 2, 2, 165cm
6, 3, 3, B型
7, 4, 1, 45kg
8, 4, 2, 180cm
ParentIDは、名簿テーブルのIDに対応しています。
Typeは、1が体重、2が身長、3が血液型です。
Valueに実際の値が入っています。
ここで、「既婚者」を全員抽出して、"登録されている場合は"その血液型を表示するSQLを書きたいのですが、うまく行きません。どうしたらよいでしょうか?
結果は次のようになります。
ID, Name, BllodType
1, 田中, AB型
2, 鈴木, null
4, 中村, null
Select 名簿.ID, 名簿.Name, 属性.Value from 名簿 [Inner/Left] Join 属性 on 名簿.ID = 属性.ParentID Where 名簿.IsMarried = True AND 属性.Type = 3
このようにすると、血液型が登録されている田中さんしか表示されません。
条件指定を外すと体重や身長も表示されます。
ExcelのVBAからADODBでAccessのmdbファイルにアクセスしています。
Windows 7 64bit、Office 2007です。
A 回答 (7件)
- 最新から表示
- 回答順に表示
No.7
- 回答日時:
Access持ってないので、確認はできませんが。
#6 の最初の方法だと
名簿.ID,属性.type
4,1
4,2
ができるので、4,NULLの行が無い→where に該当しない、となりそうですが
その次のやつは
Select 名簿.ID, 名簿.Name, 属性.Value from 名簿
Left Outer Join
(select ParentID,Value from 属性 where Type = 3) as T
on 名簿.ID = T.ParentID
Where 名簿.IsMarried = True
で動きませんか?
#1でエラーになる、というのも気になります。
No.6
- 回答日時:
>エラーメッセージは「結合式がサポートされていません」とだけ表示されます。
ということだったのですね。了解です。
Select 名簿.ID, 名簿.Name, 属性.Value from 名簿
Left Outer Join 属性 on 名簿.ID = 属性.ParentID
Where 名簿.IsMarried = True
AND (属性.Type = 3 or 属性.Type is null)
または、
Select 名簿.ID, 名簿.Name, 属性.Value from 名簿
Left Outer Join
(select 属性.Value from 属性 where 属性.Type = 3) as 属性
on 名簿.ID = 属性.ParentID
Where 名簿.IsMarried = True
※ as 属性 は、単に 属性 かも。
あたりではどうでしょう?
(また、サポートされていませんとかでるかもしれませんが。)
ありがとうございます!!できました!
AND (属性.Type = 3 or 属性.Type is null)
職人技というか頭が柔らかいというか、感服しました。
Where 句を追加することも試みていたのですが、 3 以外を除外したり、> 3 and < 3 とかで範囲を除外しようとしたり、こざかしいことばかり試していました。AND + () にして、9 と null の両方を取れば条件に一致するのですね。
2つめのSQL文は動きませんでした。
as の部分を変えたり、カッコの中と外でテーブル名に異なる別名を付けましたがうまくどれもfrom文がおかしいとか、結合分がサポートされていないとか表示されてしまいました。
勉強になりました!助かります
No.4
- 回答日時:
テーブル構造を変更出来ないのであれば、強制的に列[ BloodType]を生成するしかないと思いますよ。
SELECT 名簿.Name, (Select Value FROM 属性 WHERE 属性.ParentID=名簿.ID AND 属性.Type=3) AS BloodType
FROM 名簿
WHERE (((名簿.IsMarried)=True));
*添付図ではNull を空で表示しています。
ありがとうございます。
workaround として、すべての名簿IDに対して、type 3の属性レコードを1件ずつ自動で生成して、血液型はとりあえず "" にするということをしていました。これはこれで動いているのですが、ソフトウェア側から操作した場合に血液型レコードのない人名が登録されてしまうので困っていました。
せっかく教えていただきましたが、シンプルな Where 句で AND (3 or null) のSQLを使うことにします。
お手間を取らせました。
勉強して出直してきますので、またよろしくお願いします。
No.3
- 回答日時:
ANO.1の方のSQLは間違っているように見えないのだけど。
(エラーが出たときは、どういうエラーがでたか詳しく書かないと答えようもないですよ。)
それはさておき、本題のほうですが。
Select 名簿.ID, 名簿.Name, 属性.Value
from 名簿 Left Outer Join 属性
on 名簿.ID = 属性.ParentID
AND 属性.Type = 3
Where 名簿.IsMarried = True
ではどうですか?
Left Join ってものによっては、Left Inner Joinの省略形で、
Inner Koinて書いているのと同じだったりすることもあるので。
ありがとうございます。
エラーメッセージは「結合式がサポートされていません」とだけ表示されます。
「AND 属性.Type = 3」をそっくり削除すると動作します(期待動作ではありませんが)。
「名簿.ID = 属性.ParentID AND」部分を削除しても同じエラーが出るので、On の後に 属性.Type = 3 という形式は使えないのではないかと疑っています。
エクセルVBAからADODBで操作する場合には使えない書き方なのかもしれませんね。
No.2
- 回答日時:
【属性】
ID___________1
ParentID_____1
Weight_______55Kg
Height_______170cm
BloodType____AB型
Q、どうしたらよいでしょうか?
A、一番良いのは、テーブル「属性」の列を上のように変更。
更に言えば、主テーブルと属性テーブルとに分離する必要性はないようですね。
<理由>列[ID]、列[ParentID]の値は常に一致するから。
【名簿】
ID___________1
Name_________田中
IsMarried____True
Weight_______55Kg
Height_______170cm
BloodType____AB型
とテーブル「名簿」の設計を変更すれば、もっと簡単に事は達成できるかと思いますよ。
ありがとうございます。
残念ながらこの構造は変えられないのです。
あるソフトウェアが扱うデータベースを、エクセルから強制的に変更しようというもので、構造を変えるとソフトウェア側が対応できなくなってしまうのです。
No.1
- 回答日時:
属性の中から、Type=3のものだけを抜き出して、joinすればよいでしょう。
JOINのONで指定できるのは、tableA.colA=tableB.colB だけではありません。
Select 名簿.ID, 名簿.Name, 属性.Value from 名簿
Left Join 属性 on 名簿.ID = 属性.ParentID AND 属性.Type = 3
Where 名簿.IsMarried = True
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
映画のエンドロール観る派?観ない派?
映画が終わった後、すぐに席を立って帰る方もちらほら見かけます。皆さんはエンドロールの最後まで観ていきますか?
-
フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
あなたが普段思っている「これまだ誰も言ってなかったけど共感されるだろうな」というあるあるを教えてください
-
映画のエンドロール観る派?観ない派?
映画が終わった後、すぐに席を立って帰る方もちらほら見かけます。皆さんはエンドロールの最後まで観ていきますか?
-
海外旅行から帰ってきたら、まず何を食べる?
帰国して1番食べたくなるもの、食べたくなるだろうなと思うもの、皆さんはありますか?
-
天使と悪魔選手権
悪魔がこんなささやきをしていたら、天使のあなたはなんと言って止めますか?
-
GROUP BYを行った後に結合したい。
Oracle
-
SQLで、Join句で結合したテーブルにデータが無い場合について
SQL Server
-
select文の実行結果に空白行を入れたい
MySQL
-
-
4
SQL文のwhere条件文で使う <> の意味はなんですか
その他(データベース)
-
5
SQL Left Join で重複を排除するには
SQL Server
-
6
CASE文のエラーについて
Oracle
-
7
Null同士の結合
その他(データベース)
-
8
SQL文で素早くNULLを除外する方法
SQL Server
-
9
ACCESSで空白のデーターをクエリで判定/識別する方法を教えてくださ
Access(アクセス)
-
10
【SQL】他テーブルに含まれる値に合致する行を抽出
その他(データベース)
-
11
Java-jspの画面入力値保持について
Java
-
12
データベースのINT型項目にNULLはNG?
MySQL
-
13
副問合せにLIKE文を使う方法はないでしょうか?
Oracle
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Accessでテーブル名やクエリ名...
-
Accessレコードの追加や変更が...
-
Accessでvlookupみたいなことは...
-
デザインビューで、連結式 を...
-
SQLで日付を条件に削除したい
-
2つのテーブルを比較して一致し...
-
SQLで条件指定結合をしたいがNU...
-
時間の足し算
-
3つの表を1つに縦に連結する
-
ACCESSで指定されたテーブルか...
-
Access 複数テーブルのレコー...
-
ACCESSに同時アクセス(編集)を...
-
SQLServerのデータをMDBファイ...
-
アクセスのメインフォームとサ...
-
Accessクエリでの、LIKE条件
-
Accessでのテーブルのコピー
-
採点のDBを作りたい
-
アクセスのテーブル間で同じ値...
-
翌営業日までの日数をSQLで求め...
-
テーブルの値の先頭2桁を全て...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Accessでテーブル名やクエリ名...
-
access テーブル内のレコード...
-
Accessレコードの追加や変更が...
-
Accessクエリでの、LIKE条件
-
Accessの追加クエリで既存のテ...
-
Accessでvlookupみたいなことは...
-
3つの表を1つに縦に連結する
-
ACCESSに同時アクセス(編集)を...
-
デザインビューで、連結式 を...
-
ACCESSで指定されたテーブルか...
-
Accessでテーブルからテーブル...
-
2つのテーブルを比較して一致し...
-
ツリー構造をRDBで表現するには?
-
SQLで条件指定結合をしたいがNU...
-
リンクテーブルを CopyObject ...
-
パススルークエリをテーブル作...
-
Accessでテーブルにパスワード...
-
SQL: SELECT UNIONすると文字数...
-
時間の足し算
-
INSERT時にデータ登録とmaxの発...
おすすめ情報