You Asked
Dear Tom,
Ques1:
--------
I have the following tables.
create table t1 (
id number,
k1 number,
k2 number,
dt date,
CONSTRAINT pk_t1 Primary Key(id)
);
create table t2 (
id number,
k1 number,
dt date,
CONSTRAINT fk_t2_t1 FOREIGN KEY(id)
REFERENCES t1 (id)
) ;
create table t3 (
id number,
k2 number, --Fk to t1.k2
dt date,
CONSTRAINT fk_t3_t1 FOREIGN KEY(id)
REFERENCES t1 (id)
) ;
I want to update t1.dt with the minimum of the t2.dt and t3.dt for the following condition. What is the best way to do this?
Cond:
=======
t1.id = t2.id and t1.k1 = t2.k1
t1.id = t3.id and t1.k1 = t3.k2
update t1 set dt = (select min(mdt) from
(
select t2.id, t2.dt mdt from t2, t1 where t1.id = t2.id and t1.k1 = t2.k1
union all
select t3.id, t3.dt mdt from t3, t1 where t1.id = t3.id and t1.k1 = t3.k2
) x
where t1.id = x.id
)
where exists (select null from ....)
or
update t1 set dt = (select min(mdt) from
(
select t2.id, min(t2.dt) mdt from t2, t1 where t1.id = t2.id and t1.k1 = t2.k1
group by t2.id
union all
select t3.id, min(t3.dt) mdt from t3, t1 where t1.id = t3.id and t1.k1 = t3.k2
group by t3.id
) x
where t1.id = x.id
)
where exists (select null from ....)
Is the above approach correct?
Ques2:
--------
Is subquery_factoring_clause doesn't work with updates?
In the above case, I want to have the subquery "x" under "WITH" clause and replace the subquery "x" on the "exists" part and the other part of the update.
thanks,
and Tom said...
1) me, well, me I would not update T1 at all. T1 should get mdt from t2 and t3 at run time. The INSTANT you do the update, the data is all out of date again - -people modify t2 and t3 and bamm, data is not valid.
Just use the view v:
ops$tkyte@ORA920> insert into t1 values ( 1, 1, 1, sysdate );
1 row created.
ops$tkyte@ORA920> insert into t2 values ( 1, 1, sysdate );
1 row created.
ops$tkyte@ORA920> insert into t3 values ( 1, 1, sysdate-10 );
1 row created.
ops$tkyte@ORA920>
ops$tkyte@ORA920> insert into t1 values ( 2, 2, 2, sysdate );
1 row created.
ops$tkyte@ORA920> insert into t2 values ( 2, 2, sysdate-20 );
1 row created.
ops$tkyte@ORA920> insert into t3 values ( 2, 2, sysdate );
1 row created.
ops$tkyte@ORA920>
ops$tkyte@ORA920>
ops$tkyte@ORA920>
ops$tkyte@ORA920> create or replace view v
2 as
3 select t1.*, least( (select min(dt) from t2 where t2.id = t1.id),
4 (select min(dt) from t3 where t3.k2 = t1.k1) ) mdt
5 from t1
6 /
View created.
ops$tkyte@ORA920> select * from v;
ID K1 K2 DT MDT
---------- ---------- ---------- --------- ---------
1 1 1 28-FEB-03 18-FEB-03
2 2 2 28-FEB-03 08-FEB-03
But if you really wanted, you can:
ops$tkyte@ORA920>
ops$tkyte@ORA920> update v set dt = mdt;
2 rows updated.
ops$tkyte@ORA920>
ops$tkyte@ORA920> select * from v;
ID K1 K2 DT MDT
---------- ---------- ---------- --------- ---------
1 1 1 18-FEB-03 18-FEB-03
2 2 2 08-FEB-03 08-FEB-03
2) WITH doesn't make sense. You can up date a view however like this:
ops$tkyte@ORA920> update (
2 select t1.*, least( (select min(dt) from t2 where t2.id = t1.id),
3 (select min(dt) from t3 where t3.k2 = t1.k1) ) mdt
4 from t1 )
5 set dt = mdt;
2 rows updated.
that is your "factored" subquery.
Rating
(5 ratings)
Is this answer out of date? If it is, please let us know via a Comment