SQLのUPDATE文に関して教えて下さい
まだまだ初心者で勉強中なのですが、ご教授をお願い致します。
2つのテーブルがあり同じ条件になったレコードのある項目を別のもう片方の項目にセットしたいのですが上手くいきません。
具体的には以下の通りです。
【テーブル1】
品番、 規格、 取引先、 日付
A1 XXX T001 2010/01/01
A1 YYY T002 (空白)
B1 XXX T001 (空白)
C1 ZZZ T003 (空白)
【テーブル2】
品番、 規格、 取引先、 受入日
A1 XXX T001 2010/01/01
A1 YYY T002 2010/03/01
B1 XXX T001 (空白)
テーブル1の「日付」が(空白)のレコードを対象に、
テーブル1の「品番+規格+取引先」とテーブル2の「品番+規格+取引先」が同じな場合、
テーブル1の「日付」項目にテーブル2の「日付」項目をUPDATEしたいと考えています。
結果を以下のようにしたいです。
【テーブル1】
品番、 規格、 取引先、 日付
A1 XXX T001 2010/01/01
A1 YYY T002 2010/03/01 ←ここが今回更新される
B1 XXX T001 (空白)
C1 ZZZ T003 (空白)
以前この場で教えて頂いたものを参考に以下のような感じで考えていたのですがエラーになります。
update テーブル1 set テーブル1.日付 = テーブル2.受入日
where テーブル1.日付 Is Null and
(concat(concat(品番, 規格), 取引先)) in (select (concat(concat(品番, 規格), 取引先)) from テーブル2) ;
ERROR at line 1:
ORA-00904: "テーブル2"."受入日": invalid identifier
set文のところの記述方法がわかりません。
宜しくお願い致します。
No.6ベストアンサー
- 回答日時:
>>また主キーにすることで記述を変えることが出来る
主キーである必要はありません。
簡単に書きすぎたので、少し説明しますと……
No.1の2番目のUPDATE文の場合、
更新される方(この場合テーブル1)の行に対して
更新する方(この場合テーブル2)に該当する行が複数存在すると、
どのデータで更新すればよいのかOracleにはわからないわけです。
テーブル2が一意になることを保障してやる必要があります。
保障する方法の1つが主キーを貼ることなのですが、
テーブル2のキー項目(品番+規格+取引先)で
一意索引を作成してもかまいません。
# うまく説明できてないな……
# 「更新可能なビュー」「ORA-01779」あたりで検索してください。
>>in条件が使えない理由
特定のデータでうまくいかないのであれば、そのデータを……
Oracleがエラーメッセージを返すのであれば、そのメッセージを……
うまくいかない状況を挙げてみてはいかがでしょう。
# 両テーブルの主キーは何だろう?
No.5
- 回答日時:
>”いろいろ問題”に関して少しだけ具体的な事例があれば教えて下さい。
key1,key2,key3
AAA,AAA,AAA
AA,AA,AAAA
AA,AAA,AAAA
A,A,AAAAAAA
key||key2||key3やconcat(concat(key1,key2),key3)は、Aの並び9個になります。
異なるレコードにも関わらず、区別がつきません。
(key1,key2,key3) in (select key1,key2,key3 from hoge)
は、当然区別します。
なぜ、in条件が使えないのか、未だに理解できていませんが、in条件が使えない、
または効率的に使わないほうが良い場合には、existsを使うのが良いでしょう。
同様に、not in条件が非効率な実行計画となる場合も、not existsを試行してみると良いかと思います。
オプティマイザが賢ければ、同じ計画となるべきところでも、実際は異なるケースも多々あるので、
都合の良い方を選択的に採用すると良いと思いますよ。
k_o_r_o_c_h_a_n様、
非常に分かりやすいご説明ありがとうございます。
同じ並びになってしまう可能性があるということが非常によく分かり理解できました。
in条件が使えない理由は色々試してみます。
まだまだ最初の一歩を踏み出したところですのでこれからもご教授お願い致します。
No.4
- 回答日時:
>>複数項のIN条件がエラー
まさか……
キー(と思われる)項目にNULLが入っていたりしないでしょうねえ(^^;
この回答への補足
dda167様、
ご回答ありがとうございます。
NULL確認しましたが、存在しませんでした。
全てのレコードのキー項目にデータが入っています。
No.2
- 回答日時:
前回の質問で、締め切り済みでコメントできなかったのですが・・
CONCATで単一文字列にして、IN条件とするのは、いろいろ問題があります。
なぜ、複数項のIN条件がエラーになったのか気になりますが、どうしても使えないなら、
existsでの書き換えが可能です。
例えば、今回のSQLの場合だと、次のような条件式への書き換えになります。
(更新項目の右辺は、今回の質問に対する回答に相当します)
update テーブル1
set テーブル1.日付 =
(
select テーブル2.受入日 from テーブル2
where テーブル1.品番=テーブル2.品番 and テーブル1.規格=テーブル2.規格 and テーブル1.取引先=テーブル2.取引先
)
where テーブル1.日付 Is Null and
exists(
select 1 from テーブル2
where テーブル1.品番=テーブル2.品番 and テーブル1.規格=テーブル2.規格 and テーブル1.取引先=テーブル2.取引先
);
この回答への補足
k_o_r_o_c_h_a_n様、
前回に引き続きご支援ありがとうございます。
前回自分なりに出来たと思っていたのですが、まだまだでした。
ご回答頂いた中に
>CONCATで単一文字列にして、IN条件とするのは、いろいろ問題があります。
とありますが、”いろいろ問題”に関して少しだけ具体的な事例があれば教えて下さい。
何か懸念点があればconcat方法を止めないといけないと思いました。
宜しくお願い致します。
No.1
- 回答日時:
テーブル2の受入日がNULLの場合は除外しています。
update テーブル1 set 日付 = (
select 受入日 from テーブル2
where テーブル2.品番 = テーブル1.品番
and テーブル2.規格 = テーブル1.規格
and テーブル2.取引先 = テーブル1.取引先
)
where テーブル1.日付 is null
and exists (
select * from テーブル2
where テーブル2.品番 = テーブル1.品番
and テーブル2.規格 = テーブル1.規格
and テーブル2.取引先 = テーブル1.取引先
and テーブル2.受入日 is not null
);
たとえば、品番+規格+取引先が主キーの場合、
以下のように書くこともできます。
update (
select t1.日付, t2.受入日
from テーブル1 t1, テーブル2 t2
where t1.品番 = t2.品番
and t1.規格 = t2.規格
and t1.取引先 = t2.取引先
and t1.日付 is null
and t2.受入日 is not null
)
set 日付 = 受入日;
この回答への補足
dda167様、
ご回答ありがとうございます。
”exists”を使ってサンプル頂いた内容で更新できることを確認しました。
また主キーにすることで記述を変えることが出来ることも分かりました。
まだまだ初心者で日々勉強の毎日ですので、また何かありましたらご支援をお願い致します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Oracle 下記のsqlで取得されるレコード以外を取得する方法ありますでしょうか。 SELECT B.番号, B 2 2022/04/20 23:21
- Oracle SQL update方法 2 2022/06/22 14:07
- Access(アクセス) アクセス テーブルの空白を変数に置換するボタンが作りたい 4 2022/07/08 11:19
- Visual Basic(VBA) access count数を変数に格納 2 2022/03/30 19:21
- Oracle sqlで質問です。 Aテーブルの情報をBテーブルに更新かけたいです。 やりたいことは、Bテーブルの受 1 2023/05/17 11:17
- Oracle sqlで質問です。 Aテーブルの登録番号をキーにBテーブルから確認番号を取得したいのですが、Bテーブ 4 2023/05/18 13:08
- その他(Microsoft Office) パワークエリの複数ファイルのデータ統合について 3 2022/07/14 17:06
- Oracle update文で質問です。 下記の条件でupdateをしたいですが、どのようにしたら良いでしょうか。 2 2022/06/23 10:51
- Oracle sqlのupdate文で質問です。 テーブルBの番号をキーにテーブルAの身長をテーブルBの身長に更新 2 2022/11/02 15:15
- SQL Server [SQLServer] テーブル名からカラム名を取得する 1 2022/08/23 21:20
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
select句副問い合わせ 値の個...
-
GROUP BYを行った後に結合した...
-
select insertで複数テーブルか...
-
SET句内で複数の条件を指定して...
-
oracleの分割delete
-
V$SGAとV$PARAMETERの確認
-
select文でフリーズします。
-
データベースの基礎かもしれま...
-
unionでマージした副問合せを結合
-
2つのテーブル結合
-
SQL 年だけ抽出
-
外部結合とor条件混在の記述方法
-
SELECTの結果で同一行を複数回...
-
unionの結果は集計はできないで...
-
Accessで別テーブルの値をフォ...
-
エクスプローラーで「2つの条件...
-
ファイル書込みで一行もしくは...
-
<SQL>条件付きで最小値レコード...
-
SQLServer 日付が直前のレコー...
-
SQL>UPDATEと同時にその件数を...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
GROUP BYを行った後に結合した...
-
select句副問い合わせ 値の個...
-
select insertで複数テーブルか...
-
SELECTの結果で同一行を複数回...
-
MERGE文を単体テーブルに対して...
-
固定値を含む結合と複数テーブ...
-
複数テーブルのMAX値の行データ...
-
他のテーブルを参照した値はupd...
-
unionの結果は集計はできないで...
-
外部結合とor条件混在の記述方法
-
oracleの分割delete
-
SET句内で複数の条件を指定して...
-
SQL GROUPで件数の一番多いレコ...
-
DELETE 文とEXISTSの使い方につ...
-
COUNTの取得方法(?)について...
-
集計後の数値が倍になる
-
SQLの書き方(チェックボックス)
-
unionでマージした副問合せを結合
-
結合と副問い合わせの違い
-
副問い合わせのinsert文
おすすめ情報