よろしくお願いします。
PHP5、MySQL5、 PEAR DB、Smarty にて開発しております。
標題にもありますように、LEFT JOINを使ってUPDATEできる方法を探しております。
●Aテーブル(親)
id | del_flag
-----------------
1 | 0
2 | 0
3 | 0
4 | 0
●Bテーブル
id | del_flag
-----------------
1 | 0
3 | 0
4 | 0
●Cテーブル
id | del_flag
-----------------
1 | 0
2 | 0
3 | 0
4 | 0
上記のような3つ、またはもしくはそれ以上テーブルがあったとします。
そこで、
Aテーブルの id 2 のdel_flagを1 とアップデートしたときに、
同時に全てのB、Cのテーブルの id 2 のdel_flagも 1 としたく思います。
Bテーブルには、id 2 が存在しないため、結果的にはCテーブルだけが更新されますが、
A、B,Cともに同一のid値 がある場合も考慮して、
アップデートしたいと思います。
そこで、PHP内で、一つ一つのテーブルを地道にアップデートすることは可能だとおもいますが、
一度のSQLでdel_flagの値を1とできる方法はございませんでしょうか?
お手数ですが、
具体的なクエリを書いていただけると、大変助かります。
いろいろ調べましたが、なかなか上手くいかず・・・・。
よろしくお願いいいたします。
No.4ベストアンサー
- 回答日時:
>left joinでつなげるよりスマートで効率的なのはわかりましたが、
>速度的にはどうなんでしょうね?
left joinによるオーバーヘッドを考慮すれば
おそらく個別でやった方が早いでしょう。
蛇足ですが、どうも今回の案件について疑問があります。
AテーブルについてはIDがプライマリになっていると思いますが
Bテーブル(やCテーブル)についてはどういう仕様なのでしょう?
BテーブルでもIDがプライマリなら、いっそのこと同じテーブルで管理すれば
よい案件かもしれません。
通常子テーブルというのはIDでつながっても親IDに対して複数のデータを
持つような場合有効ですが、1対1ならあえて分けている意味があるか微妙です。
また、別解ですが、Bテーブルにdel_flg自体をつけること自体に意味があるのでしょか
?
Aテーブルの正規化につかっているならAテーブルのdel_flgで処理すればよいし
場合によってBテーブルを単独で検索するとしてもAテーブルをジョインすれば
簡単にdel_flgレベルのことはできそうな気がしますが?
詳しく有難うございます!
なるほど! 少し本質が見えてきました。
AのIDはプライマリです。
B,Cテーブルは、言葉たらすでしたが、
じつは複数の同一IDを格納していまして、1対1ではない現状です。
yambejp様のおっしゃる通りでございます。
やはり、オーバーヘッドを考慮すると、
個別の方が早いのですね。
まだまだジョインすることについて慣れておらず、恐る恐る勉強しております。
また、もし 以下のようにLEFT JOIN したとして、
----------------------------------------
update A left join B on A.id=B.id left join C on A.id=C.id
set A.del_flag=1, B.del_flag=1, C.del_flag=1
where A.id=2
----------------------------------------
BやCのテーブルに
該当するID(AテーブルのプライマリID)が無いテーブル状況だと、処理はエラーとなりますよね?
その場合、今の設計的に大変困ったことになります。
なぜなら、十分にBやCにIDが存在しないことがある設計だからです。
この辺り、また自分でも試して研究しようと思いますが、
よろしれば回答下さいませ。
次に、
>また、別解ですが、Bテーブルにdel_flg自体をつけること自体
>に意味があるのでしょか?
についてです。
これは私に知識と経験のないことを証明する、根本的な解決策であると
、とてもありがたいご指摘です。
各BやCテーブルは、Aテーブルと正規化されています。
ですので、ご指摘のように、
今ふと考えると、del_flagのフィールドを各テーブルに設置しなくてもいいのだと気づきました。
ただ、いま作っているものが、上記のような正しいコントロールがされないまま開発してしまっているので、今から取り込むのはかなり厄介なことになりそうです。
でも、このような方法で、各ページで使用するデーターを取り込んでいたらと思うと、本当にバカな作りかたをしていたと後悔しています。
No.5
- 回答日時:
>BやCのテーブルに
>該当するID(AテーブルのプライマリID)が無いテーブル状況だと、処理はエラーとなりますよね?
やってみればわかりますが、エラーは出ません
また、もしも複数のSQLを投げるのに抵抗があれば、プロシージャを用意するとか・・・
DROP PROCEDURE IF EXISTS SET_FLG;
DELIMITER //
CREATE PROCEDURE SET_FLG(IN in_id INT,IN num INT)
BEGIN
SET AUTOCOMMIT=0;
START TRANSACTION;
UPDATE `table_a` SET `del_flg`=num WHERE `id`=in_id;
UPDATE `table_b` SET `del_flg`=num WHERE `id`=in_id;
UPDATE `table_c` SET `del_flg`=num WHERE `id`=in_id;
COMMIT;
END
//
DELIMITER ;
としておき
CALL SET_FLG(2,1);
この度は、いろいろと有難うございました。
プロシージャについても勉強になりました。
とにかく、今回の疑問が解決しましたので、ご報告いたいします。
お世話になりました。
また、よろしくお願いいたします。
No.3
- 回答日時:
>でも、UPDATEしたいテーブルが計8つ程ありまして、
>ずらっと8つ連呼するべきでしょうか?
8個のSQLを投げる方が、8個つないで8箇所修正するより
効率的だと思いますよ
なるほど、わかりました。
8回foreachで連呼します。
left joinでつなげるよりスマートで効率的なのはわかりましたが、
速度的にはどうなんでしょうね?
No.2
- 回答日時:
提示されたものを単純にかくとこうなります
update table_a as a
left join table_b as b on a.id=b.id
left join table_c as c on a.id=c.id
set a.del_flg=1,b.del_flg=1,c.del_flg=1
where a.id=2
でも、これって
update table_a set del_flg=1 where id=2;
update table_b set del_flg=1 where id=2;
update table_c set del_flg=1 where id=2;
と書く方がましなような気がしますが?
この回答への補足
確かに下の方がいいよな気もします・・・。
でも、UPDATEしたいテーブルが計8つ程ありまして、
ずらっと8つ連呼するべきでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Oracle SQL update方法 2 2022/06/22 14:07
- Access(アクセス) アクセス テーブルの空白を変数に置換するボタンが作りたい 4 2022/07/08 11:19
- その他(データベース) 更新クエリをリンクデータベーステーブルに実行し実行時エラー3362固有インデックスに重複する値が含ま 1 2022/09/21 11:44
- SQL Server ACCESSで表が作りたく、そのためのSQL文や設定方法を教えてください。 1 2022/08/15 12:28
- MySQL PHPとMySQLを使った掲示板の作り方 1 2022/06/02 13:00
- MySQL 【MySQL】本当に困っています。詳しい方、ご教授よろしくお願いします。 1 2023/06/03 14:18
- Oracle sqlで質問です。 aテーブルとbテーブルがあり、下記のsqlで取得したidとnameに一致しないレ 1 2022/04/20 20:34
- Access(アクセス) アクセスの更新クエリでカレントレコードのみ更新したい 1 2022/06/02 23:32
- Oracle sqlで質問です。 Aテーブルの情報をBテーブルに更新かけたいです。 やりたいことは、Bテーブルの受 1 2023/05/17 11:17
- その他(データベース) pythonでsqlight勉強中、クエリー結果の利用法教えて下さい 1 2022/04/28 20:38
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルで最後の文字だけ置き...
-
SQL Left Join で重複を排除す...
-
副問合せの書き方について
-
エクセルの関数について教えて...
-
Access パラメータクエリをcsv...
-
SQLite3でこんな便利なSQLはで...
-
MYSQLでSQLSERVERのリンクサー...
-
1テーブル&複数レコードの更新...
-
ある条件の最大値+1を初番する...
-
group byのSQLでインデックスを...
-
verilogに適したvimの設定を探...
-
mysqlのdeleteのサブクエリーで...
-
MySQLのIF文
-
クエリ表示と、ADOで抽出したレ...
-
複数テーブルのGROUP BY の使い...
-
カテゴリのDB設計について
-
テーブル作成です。どこかのス...
-
SELECT出来るのにDELETE出来な...
-
URL と行番号の指定
-
親と子供が複数のSQL取得方法
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで最後の文字だけ置き...
-
SQL Left Join で重複を排除す...
-
VIEWの元のテーブルのindexって...
-
SQLサーバから、項目の属性(型...
-
select文のwhere句に配列を入れ...
-
副問合せの書き方について
-
マイクラPC版のコマンドで効率...
-
Unionした最後にGROUP BYを追加...
-
selectした大量データをinsert...
-
SQLにて特定の文字を除いた検索...
-
[SQLServer] テーブル名からカ...
-
1テーブル&複数レコードの更新...
-
inner joinをすると数がおかし...
-
クエリ表示と、ADOで抽出したレ...
-
ある条件の最大値+1を初番する...
-
sqlで、600行あるテーブルを100...
-
複数テーブルのGROUP BY の使い...
-
insertを高速化させたい
-
PL/SQLの変数について
-
キー毎の、ある列のmaxのレコー...
おすすめ情報