
いろいろ調べたけど、わからなかったので質問します。
A表
キー、日付
10,NULL
20,NULL
30,NULL
B表
キー、日付
10,20040905
30,20040906
40,20040907
Oracle(8.1.7)上に上記のような2つの表があり、A表と、B表でキーが同じだった場合、B表の日付をA表の同じキーの日付フィールドに更新する方法はありますか?(下のような結果になりたい)
A表
キー、日付
10,20040905
20,NULL
30,20040906
1回のSQL文で更新することはできるのでしょうか?
できるのであれば、教えていただきたいと思います。
No.3ベストアンサー
- 回答日時:
結論から言うと、ほんとは全く違うんです・・・
その、#2の補足のSQLが間違ってます。#1のzabesuさんのかかれたSQLと良く比較してください。というか、update文の挙動が理解できていないようですね。
正しい、sql文、もう一度、全部書きますね。
UPDATE A表 SET A表.日付 =
(SELECT MAX(B表.日付) FROM B表
WHERE A表.キー = B表.キー);
です。#2の補足が間違っている場所は、副SELECT文のFROM句に「A表」の指定があるかないかです。
で、これ、まったく挙動が変わります。今回の場合は、付けてはいけません。
正しいSQLでは、「A表.キー」の値は、UPDATEが今処理しようとしているA表の行の値から採取されると思えばわかりやすいでしょう。
参考までに、正しいUPDATE文の挙動を簡単に説明しておきます。
ある行の更新、たとえば、キーが10の場合を考えましょう。副SELECT文のWHERE句で、「A表.キー」の値は、今まさに更新しようとしている行の「キー」は10ですから、10です。したがって、B表の「キー」が10のところをB表から探します。そして、その行の日付をUPDATEのSET句に示されるように「A表.日付」に代入します。
では、キーが20の行を更新するとしましょう。「A表.キー」は20ですから、「A表.キー=B表.キー」が成立する行はB表にはありません。よって、副SELECT文の結果はNULLです。その値が、「A表.日付」に代入されます。
元の例示のA表の日付が全部NULLですから、挙動としてはこれでokです。
ちなみに、正しい方のSQLだと、実は、MAXを付ける必要は本来無い「はず」なんです。なぜなら、おそらく、A表.キーと、B表.キーには、最低でもユニークインデックスがついているはずで、おそらくは名前からしてプライマリーキー指定がついているでしょう。この場合、「A表.キー = B表.キー」を満たすB表の行は一行しかないことをデータベースは認識できます。ですから、MAX関数でごまかして1行に見せかける必要はどこにもありません。
MAX関数が必要なのは、人間としては、SELCT文が成立する行は一行しかないことを知っているんだけれども、データベースには1行と認識できない場合です。複雑なWHERE句を書くとよく発生します。この場合は、しかたがないので、MAX関数やMIN関数で一つしかないとデータベースに対して自己主張してやります。ただし、人間が約束を破ってWHERE句が成立する行が2行以上あれば、データベースは指示通りに最大または最小の値をもって作業を継続します。(簡単な例では、A表とB表のキー列にユニーク指定もプライマリーキー指定も無い場合です。でも、この制約は、このデータベースにデータを入力する際の重要なデータチェックの要素となりますから、できれば指定した方がよいでしょうね。)
おかげさまでうまくいきました。
いろいろと教えて下さってありがとうございました。
SQL文について、もっと勉強しようと思います。
No.2
- 回答日時:
#1補足のようなエラーは、SELECT句のフィールドリストを「MAX(B表.日付)」としてしまえば回避できます。
1個の値にMAXやMIN関数を適用しても値は変りませんから。但し、B表のキーが一意である事が条件です。まあこの制約が問題になるようならもともと質問の更新は論理的に不可能ですが…
この回答への補足
mitoneko さんのようにやってみました。
「update A表 set 日付 = (select MAX(B表.日付) from A表,B表 where A表.キー = B表.キー);」
を実行した結果、A表の全レコードが更新されました。
これだと
(例)「update A表 set 日付 = '20040908';」
と同じねすよね。
UPDATE文に WHERE句が必要だと思いますが、どのように書いたら良いのでしょうか?
No.1
- 回答日時:
確認していないですけど、
update A表 set
日付 = (select B表.日付 from B表 where A表.キー = B表.キー);
というようなSQL文でいきそうな気がします。
この回答への補足
update A表 set
日付 = (select B表.日付 from A表,B表 where A表.キー = B表.キー);
でやってみましたが、「ORA-01427 単一行副問合わせにより2つ以上の行が返されます。」と表示されます。
「set 日付=」は1つを返されるようにしないといけないと思うのですが・・・
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Oracle sqlで質問です。 Aテーブルの情報をBテーブルに更新かけたいです。 やりたいことは、Bテーブルの受 1 2023/05/17 11:17
- MySQL エラー 1068 (42000): 複数の主キーが定義されていますエラー 2 2022/11/17 04:36
- Oracle update文で質問です。 下記の条件でupdateをしたいですが、どのようにしたら良いでしょうか。 2 2022/06/23 10:51
- Access(アクセス) Accessテーブルの結合で別々のテーブルのフィールドを組み合わせて値を出す方法について 2 2022/07/20 19:43
- その他(データベース) 更新クエリをリンクデータベーステーブルに実行し実行時エラー3362固有インデックスに重複する値が含ま 1 2022/09/21 11:44
- Oracle sqlのupdate文で質問です。 テーブルBの番号をキーにテーブルAの身長をテーブルBの身長に更新 2 2022/11/02 15:15
- その他(コンピューター・テクノロジー) 【Tableau Desktop】文字列から8桁の数字を日付型(yyyyMMdd)として取得 1 2023/07/31 10:17
- その他(コンピューター・テクノロジー) プリントスクリーンについて 6 2022/11/23 11:17
- マウス・キーボード 「東プレ」って何ですか? 「軸」って何ですか? 次壊れたら何を買えばよいのでしょう? 6 2022/08/30 07:56
- Oracle SQLについて教えて下さい。 主キーを持ったカラムを主キーの機能を持たせたまま カンマ区切りで文字列 1 2023/03/27 22:47
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
SQL Serverの型変換について
-
SQLで部分的にGROUP BYしたいとき
-
PL/SQLで、期間計算
-
SQL(SELECT文)を教えてください
-
今日の日付が入った行のデータ...
-
オラクルのレコードカウントの...
-
SQLサーバで和暦から西暦に変換...
-
エクセル 日付による並べ替え...
-
wordの差し込み印刷での日付表示
-
日付書式に変換でこまっています!
-
sysdateのフォーマットが変わり...
-
テーブルの主キーをdate型...
-
週の開始日・終了日を求めるSQL
-
PLSQL CHARの項目を使用した計算
-
SQLがうまくいかない!
-
WHERE句にて「30日前から今日ま...
-
日付の切り出し方法について
-
関数IFで、指定日付範囲のデー...
-
2テーブル間でフィールドの更...
-
Accessのマクロでモジュールを...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
14桁の日付(YYYYMMDDHHMMSS)を...
-
今日の日付が入った行のデータ...
-
SQLで部分的にGROUP BYしたいとき
-
Accessの数値から時間に変換す...
-
重複するIDのデータを1行にま...
-
SQLサーバで和暦から西暦に変換...
-
日付書式に変換でこまっています!
-
テーブルの主キーをdate型...
-
日数算出SQL
-
wordの差し込み印刷での日付表示
-
oracle 文字列 01:45 を時間に...
-
日付の切り出し方法について
-
Excelグラフの日付軸の日付がず...
-
WHERE句にて「30日前から今日ま...
-
SQL/Loaderでの年月日時分秒の...
-
エクセル 日付による並べ替え...
-
excel 日付のみ置換したいのです
-
DB2のSQL(日付)について
-
指定した年月までのデータを取...
-
日付の最大値レコードを取得す...
おすすめ情報