トップページに戻る    次のSQLパズルへ    前のSQLパズルへ

5-9 他テーブルの値を使用してupdate

SQLパズル

設計値テーブル       単価テーブル
ID  Parm  Value      ID  Cost
--  ----  -----      --  ----
01  長さ     30      01  null
01  高さ     25      02  null
02  長さ     50      03  null
02  高さ     30
03  長さ     50
03  高さ     30

設計値テーブルを元に単価テーブルを更新する、
単価 = 設計値(IDで紐づけ)の長さ×高さ
とする。

更新結果
単価テーブル
ID  Cost
--  ----
01   750
02  1500
03  1500


データ作成スクリプト

create table 単価(
ID   char(2),
Cost number);

create table 設計値(
ID   char(2),
Parm char(4),
Value number);

insert into 単価(ID) values('01');
insert into 単価(ID) values('02');
insert into 単価(ID) values('03');
insert into 設計値(ID,Parm,Value) values('01','長さ',30);
insert into 設計値(ID,Parm,Value) values('01','高さ',25);
insert into 設計値(ID,Parm,Value) values('02','長さ',50);
insert into 設計値(ID,Parm,Value) values('02','高さ',30);
insert into 設計値(ID,Parm,Value) values('03','長さ',50);
insert into 設計値(ID,Parm,Value) values('03','高さ',30);
commit;


SQL

--■■■この形式のupdate文だと文法エラー■■■
--update 単価 a set Cost = (select b.Value from 設計値 b
--                         where b.ID=a.ID
--                           and b.Parm='長さ') *
--                       (select b.Value from 設計値 b
--                         where b.ID=a.ID
--                           and b.Parm='高さ');

--■■■この形式のupdate文だとうまくいきます■■■
update 単価 a set (Cost) = (select (select b.Value from 設計値 b
                                     where b.ID=a.ID
                                       and b.Parm='長さ') *
                                   (select b.Value from 設計値 b
                                     where b.ID=a.ID
                                       and b.Parm='高さ') from dual);

--■■■これでもOK■■■
update 単価 a set Cost = (select b.Value * c.Value from 設計値 b,設計値 c
                           where b.ID=a.ID
                             and c.ID=a.ID
                             and b.Parm='長さ'
                             and c.Parm='高さ');

--■■■結合してpivotを使う方法■■■
update 単価 a
   set Cost = (select max(decode(b.Parm,'長さ',b.Value))
                    * max(decode(b.Parm,'高さ',b.Value))
                 from 設計値 b
                where b.ID = a.ID);


解説

一つ目のUpdate文は文法エラーでしたが、他はうまくいきました
一つ目のUpdate文の文法エラーは、パーサの仕様でしょうか?