こんにちは。DELETE文の削除条件について教えてください。
例えば下記のような2つのテーブルがあったとします。
ATABLE
KEY1(ID) KEY2(DATE) ・・・・・・・・・・
------------------------------------------------
100000 2004/09/01 ・・・・・・・・・・
200000 2004/09/01 ・・・・・・・・・・
300000 2004/09/01 ・・・・・・・・・・
BTABLE
KEY1(ID) KEY2(DATE) CODE ・・・・・・・・・・
------------------------------------------------
100000 2004/09/01 0 ・・・・・・・・・・
200000 2004/09/01 0 ・・・・・・・・・・
300000 2004/09/01 1 ・・・・・・・・・・
この2つのテーブルで、BTABLEのCODEが1のレコードにKEYで関連付くATABLEのレコードを削除したいのです。
プログラムの中では対応できるのですが、SQL1文で実行させることはできるでしょうか?
とりあえず下記のように作ってみました(いたずらに長いかもしれませんが)。
DELETE FROM ATABLE WHERE
KEY1 IN (SELECT ATABLE.KEY1 FROM ATABLE,BTABLE WHERE ATABLE.KEY1 = BTABLE.KEY1 AND ATABLE.KEY2 = BTABLE.KEY2 AND BTABLE.CODE = 1) AND
KEY2 IN (SELECT ATABLE.KEY2 FROM ATABLE,BTABLE WHERE ATABLE.KEY1 = BTABLE.KEY1 AND ATABLE.KEY2 = BTABLE.KEY2 AND BTABLE.CODE = 1)
これで良い/悪い、もっと簡潔にできる、などありましたら是非お聞かせ願えますでしょうか?
よろしくお願いします。
No.4ベストアンサー
- 回答日時:
#3です。
おそらく、私のsqlは、標準SQLをサポートする大概のdbmsで有効だと思います。リストの比較は、どうかしら・・・この文法をsql serverがサポートしているかどうかはちょっと知りません。
ちなみに、元のh164さんのsqlですが、どうも違和感を感じるなと思ったら、やっぱり、まずいです。微妙な問題が潜んでいます。
atable
key1 key2 ・・・
--------------------------
10000 2004/09/01
10000 2004/09/02
20000 2004/09/01
20000 2004/09/02
btable
key1 key2 code
--------------------------
10000 2004/09/01 1
10000 2004/09/02 0
20000 2004/09/01 0
20000 2004/09/02 1
というデータを考えたとき、おそらく、削除レコードは、10000,2004/09/01と20000,2004/09/02の二つのレコードだと思われるでしょうが・・・
実は、全部のレコードが削除されます。
たとえば、10000,2004/09/02のレコードですが、まず、第一の比較に置いて10000,2004/09/01が副select文の結果セットに存在するので、key1の条件は真です。第二の比較でも同様に、副select文の結果セットに20000,2004/09/02が存在するので、この条件も真となります。というわけで、本来削除されるはずのない、10000,2004/09/02のレコードは、削除されます。
複数フィールドにおける比較を、各フィールドの比較のAND条件で結合する時は、よほど注意をしないとこういう事があります。ご注意を。
#1および、#2の方の回答では、この問題は発生しません。リストとして同時に比較しているからです。
#3の私のSQLも大丈夫なはずです。レコードの比較時に、元のDELETE対象の現在の操作行を連動させているからです。(従って、副SELCT文のFROM句にはATABLEの指定がありません。これは、誤記ではありませんのでご注意を。)
No.3
- 回答日時:
delete from atable a
where exist (select * from btable b
where a.key1=b.key1 and
a.key2=b.key2 and
b.code=1);
でいけそうな気がします。
今テストできないので自信なしとしておきます。
この回答への補足
回答を頂いた方々、どうもありがとうございます。
最初、私が書いた物より随分簡潔になりましたね。見易いです。
ちなみに、このSQLはSQL Serverでも動作しますでしょうか?(一応、両方の環境でやってみたいもので)
情報を小出しにしてしまい、申し訳ありません。
また、このカテゴリ(Oracle)にはあてはまらないかも知れませんが、よろしければご返答ください。
No.2
- 回答日時:
DELETE FROM ATABLE WHERE
( KEY1, KEY2 ) IN (
SELECT KEY1, KEY2
FROM BTABLE
WHERE CODE=1
)
動作チェックをしておりませんが、大丈夫だと思います。
本来ならポイントを発行差し上げたいのですが、回答No1のご回答のna_kirajp様よりほんの数分の差ですが遅いご回答でしたので、ポイントを2名様にしかつけられないこともあり、今回はポイントの発行はなしとさせて頂きます。
ですが、感謝の気持ちに変わりないということはご理解下さい。ありがとうございました。
No.1
- 回答日時:
こんにちは
提示のSQLで基本的に考え方は合っているし問題ないと思いますが、他の例として
delete from ATABLE where (ATABLE,KEY1,ATABLE,KEY2)
in (select KEY1,KEY2 from BTABLE where code=1);
なんて言うのはどうでしょうか?
違いは、BTABLEを一度参照するだけでATABLEを消せるので
パフォーマンス的には多少良いかと・・・
ありがとうございました。
回答No2のGoF様と同内容のご回答でしたが、回答時間の関係でこちらにポイントを差し上げることにします
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- MySQL MYSQL エラー 2 2022/10/18 11:37
- MySQL エラー 1068 (42000): 複数の主キーが定義されていますエラー 2 2022/11/17 04:36
- JavaScript Json のキーと値の出力の違いについて 2 2022/06/14 20:22
- MySQL my_itemsテーブルのIDにAUTO_INCREMENT を追加ができるかで 1 2023/01/03 09:09
- MySQL 何にかが違うから エラーなんでしょうね! 2 2022/09/18 05:28
- PHP php エラー 2 2022/10/23 16:43
- Visual Basic(VBA) VBAコードが作動せず、どこに問題があるのか教えて下さい。 3 2023/06/13 13:20
- Visual Basic(VBA) エクセルVBAについて 8 2022/07/13 22:41
- Ruby pandasでsqlite3にテーブル作成・追加・読み出しでindexの取り扱い方教えてください 5 2023/03/08 09:57
- 大学受験 英作文の添削をお願いしたいです。 2 2022/08/19 20:37
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ORMについて
-
【PL/SQL】FROM区に変数を使う方法
-
SELECT FOR UPDATE で該当レコ...
-
大量レコードをTRUNCATEせずに...
-
osqleditについて
-
MERGE文について
-
これをSQL文で出来るでしょうか?
-
トランザクションログを出力せ...
-
アクセスのレポートでレコード...
-
「数字で始まらない」ものを抽...
-
SQLで条件にヒットしたレコード...
-
AccessのSQL文で1件のみヒット...
-
SQL*Loader Append
-
group byの並び順を変えるだけ...
-
where句中のtrim関数について
-
BLOB型項目をSQLの検索条件に指...
-
単一グループのグループ関数で...
-
引数によってwhere句を切り替え...
-
デフォルトでデータが表示され...
-
【SQL】違うフィールド同士の集...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
単一グループのグループ関数で...
-
【PL/SQL】FROM区に変数を使う方法
-
SELECT FOR UPDATE で該当レコ...
-
AccessのSQL文で1件のみヒット...
-
where句中のtrim関数について
-
アクセスのレポートでレコード...
-
group byの並び順を変えるだけ...
-
引数によってwhere句を切り替え...
-
SQL*Loader Append
-
SQLで条件にヒットしたレコード...
-
updateで複数行更新したい
-
データ
-
トランザクションログを出力せ...
-
「数字で始まらない」ものを抽...
-
大量レコードをTRUNCATEせずに...
-
osqleditについて
-
BLOB型項目をSQLの検索条件に指...
-
これをSQL文で出来るでしょうか?
-
ACCESS レコードの並び順について
-
【SQL】違うフィールド同士の集...
おすすめ情報