お世話になっております。
今回、以下のような3つのテーブルから情報を引き出したいのですが、
うまくいかず困っております。
【TABLE_A】
a_no | animal_name |
------+------------+
0001 | uma |
0002 | usagi |
0003 | kirin |
【TABLE_B】
b_no | fish_name |
------+----------+
000A | ayu |
000B | suzuki |
000C | kurodai |
【TABLE_C】
NO | a_no1 | a_no2 | b_no1 | b_no2 |
----+-------+-------+-------+-------+
1 | 0001 | 0003 | null | 000A |
2 | 0002 | null | 000C | 000B |
3 | 0001 | 0002 | null | null |
TABLE_Cをベースに、A、Bのテーブルから該当データのname値を取ってきたいのですがうまくいきません。
私が求める結果は以下のような感じです。(条件:WHERE NO = 1)
NO | a_no | animal_name | b_no | fish_name |
-----+------+------------+------+----------+
1 | 0001 | uma | null | null |
1 | 0003 | kirin | 000A | ayu |
下記のように、INNER JOIN句を使ったりして四苦八苦してみたのですが、いまいち上手く抽出できません。
SELECT c.NO, a.a_no, a.animal_name, b.b_no, b.fish_name
FROM (TABLE_C c
INNER JOIN TABLE_A a
ON c.a_no1 = a.a_no
OR c.a_no2 = a.a_no )
INNER JOIN TABLE_B b
ON c.b_no1 = b.b_no
OR c.b_no2 = b.b_no
WHERE c.NO = 1;
上記だと、
NO | a_no | animal_name | b_no | fish_name |
----+-------+------------+------+----------+
1 | 0001 | uma | null | null |
1 | 0003 | kirin | 000A | ayu |
1 | 0003 | kirin | 000A | ayu |
のように、余計に重複して結果が返されてきてしまいます。(3行目は2行目と同じ結果なのでいらないのです・・・)
何か良い構文はありませんでしょうか?;;
宜しくお願い致します!
(環境は、MySQL 4.1.1です。)
No.2ベストアンサー
- 回答日時:
1レコードから2項目(行)なので、ユニオンでしょう。
また、結合元にNullがあるので、Left Join でないとレコードが抜けます。
SELECT C.NO,A.a_no,A.animal_name,B.b_no,B.fish_name
FROM (TABLE_C C LEFT JOIN TABLE_A A ON C.a_no1=A.a_no)
LEFT JOIN TABLE_B B ON C.b_no1=B.b_no
UNION
SELECT C.NO,A.a_no,A.animal_name,B.b_no,B.fish_name
FROM (TABLE_C C LEFT JOIN TABLE_A A ON C.a_no2=A.a_no)
LEFT JOIN TABLE_B B ON C.b_no2=B.b_no
回答ありがとうございます!
UNION句がありましたね・・・
下記のような感じで実現できました!
SELECT C.NO,A.a_no,A.animal_name,B.b_no,B.fish_name
FROM (TABLE_C C INNER JOIN TABLE_A A ON C.a_no1=A.a_no)
INNER JOIN TABLE_B B ON c.b_no1=B.b_no
WHERE C.NO = 1
UNION
SELECT C.NO,A.a_no,A.animal_name,B.b_no,B.fish_name
FROM (TABLE_C C INNER JOIN TABLE_A A ON C.a_no2=A.a_no)
INNER JOIN TABLE_B B ON C.b_no2=B.b_no
WHERE C.NO = 1
なぜかleft joinを使うと、NO以外すべてnullという不思議な列が出てきてしまったので、inner joinを使いました(@_@)
追加質問なのですが、
今回のように、union句でselect文を繋げて一回のSQLでデータを取得する方法と、
php側で(LAMP環境です)TABLE_AとTABLE_Cを比較、その後TABLE_AとTABLE_Cを比較、というように2度SQLを投げるのと
どちらがパフォーマンス的には良いのでしょうか?
実は、実環境では、
a_no1, a_no2, a_no3......a_no8
b_no1, b_no2, b_no3......b_no8
のように、8個ずつ値を取らなければならず、
UNIONで繋げようとした場合、すごく長いSQL構文になりそうで・・・。
また、何か他に良い方法等ございましたらご教授下さい。
よろしくお願い致します!
No.4
- 回答日時:
>どちらがパフォーマンス的には良いのでしょうか?
普通、1回で出来ることを2回でやるのは効率が悪いに決まっています。
今回の場合も当てはまると思います。SQLが長すぎて、1回あたりの
限界をこえるような場合以外、回数の少ない方を選ぶべきです。
>実は、実環境では
業務要件がはっきり分からないので、軽率なことはいえませんが、
1レコードに類似項目を8個も持つのは如何なものかと思います。
プロジェクトの進捗が浅いなら再設計も選択肢に入れるべきかも…
何度もありがとうございます。
長文の複雑なSQLを一度に投げるのとシンプルなSQL2回投げるのでは、もしかしたらシンプルな方が・・・とか深読みしたのですが、やっぱり1回の方がベストなのですね!
私は設計に携わっていないのですが、おそらく再設計する予定もないと思うのでこのまま頑張ります。
ありがとうございました!
No.3
- 回答日時:
列を行に変換するのは簡単ではありません。
No2の回答に書かれたunion(本来ならunion allを使うべき)が正解です。
今はno8までですが、将来的にno9ができてもいいようにテーブル構造を以下のようにするのが好ましいでしょう。
【TABLE_C】
NO | renban | a_no | b_no |
------+----------+--------+--------|
1 | 1 | 0001 | null |
1 | 2 | 0003 | 000A |
1 | 3 | null | null |
1 | 4 | null | null |
1 | 5 | null | null |
1 | 6 | null | null |
1 | 7 | null | null |
1 | 8 | null | null |
2 | 1 | 0002 | 000C |
2 | 2 | null | 000B |
回答ありがとうございます。
すいません、例の書き方が悪かったです;;
一意な連番を格納するカラムも、きちんと存在しております。
ご忠告、ありがとうございました!
No.1
- 回答日時:
第一にTABLE_Cの構造が冗長で、SQLとしてはメタメタな感じですが
これを構造から変える可能性はないのでしょうか?
このままだとデータ管理上もオーバーヘッドがおおきく
パフォーマンスも期待できないかと。
とりあえず、いまのままでやるなら縦軸と横軸がずれているので
ピボットテーブルをつかうことになるかなぁ・・・
回答ありがとうございます。
正直私も詳しければ改善案等出したいところなのですが、まだそこまで行きつかず;
現状のテーブルで行うしかないのです。
ピボットテーブルという方法もあるのですね・・・勉強不足です;;
少し調べてみましたが、ちょっと難しそうなので理解に時間がかかりそう・・・落ち着いたら勉強したいと思います。
ありがとうございました!
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- MySQL あと、MySQLの文字コードはutf8 気になりますね 1 2022/12/01 07:22
- その他(プログラミング・Web制作) Pythonで会員サイトの自動ログイン ID Nameがない 1 2022/12/16 02:09
- Oracle SQL update方法 2 2022/06/22 14:07
- AJAX JavascriptからPHPへのAjax通信でnullが返ってくる 3 2022/08/03 22:00
- JavaScript 1日1回引けるJavaScriptおみくじについて 1 2022/12/12 22:28
- MySQL PHPとMySQLを使った掲示板の作り方 1 2022/06/02 13:00
- MySQL `picture` varchar(255) のコマンドで間違いないでしょうか? 1 2022/11/21 04:08
- PHP コメント機能に返信欄を矢印で追加したい 1 2022/05/09 21:17
- MySQL エラー 1068 (42000): 複数の主キーが定義されていますエラー 2 2022/11/17 04:36
- MySQL テーブル作成です。どこかのスペルが間違っているか記号など スペースかな? 1 2022/10/01 05:08
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「総降水量が100mm以上になる...
-
utf8bomとutf8mb4の違いがいま...
-
テーブル名が可変の場合のクエ...
-
データベースの接続に失敗して...
-
#1062 - '0' は索引 'PRIMARY' ...
-
MySQLのテーブル作成でハイフン...
-
SQLです!!教えてください。
-
SQLあってますか?こう?
-
【初歩】ラジオボタンをつかっ...
-
SQLで漢字名称を都道府県や市区...
-
SQL構文です 画像のようにした...
-
SELECT * FROM `生徒名簿` INNE...
-
初心者Mysqlの関数のsubstring...
-
このSQLあってますか?教えてく...
-
SQLです!!教えてください。あ...
-
下記の問合せを行うクエリを、 ...
-
データベースの複製の仕方(mysql)
-
htmlコードで書かれた表にphpで...
-
PHPとMySQLを使った掲示板の作り方
-
SQLでカラムを追加し、条件に合...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Null値が入れられない
-
nullと同じく空白をCountしない...
-
SQLでLIMIT句を入れるとエラー...
-
NULLを含む列の足し算
-
SQL文を入力したらエラー
-
テーブル作成時に、「`id` int(...
-
MySQLの特定のカラムの内容を全...
-
phpとSQLで複数条件で検索する...
-
複雑なSQLですが、教えてくださ...
-
MySQLで関連したデータを横に並...
-
【初歩】 SELECT文で意図した照...
-
phpでnot null、a_iでテーブル作成
-
SQLのコマンドでif構文
-
MySQLで同じデータにフラグ付け...
-
MySQLで項目の反復定義(COBOL...
-
質問内容の仕様のSQLがわからな...
-
SQL文でダブルクォートか
-
mysqlのselectについて
-
計算結果でtrueならフラグをつ...
-
MySQLでのテーブル名取得に制限...
おすすめ情報