Update table using the values of other table
I want to clean up my table:
rid(PK) rval
----------- ----------
10 test
11 Rtest
12 dummy
13 test
14 Rtest
to remove the duplicate values from column rval
, so I end up with:
rid(PK) rval
----------- ----------
10 test
11 Rtest
12 dummy
But I have another table with a foreign key relationship which uses the values I want to delete:
ruid rid(FK)
---------- ----------
1 10
2 10
3 12
4 13
5 13
6 14
7 14
so before I delete, I need to update that table to use the matching rid
that I'm keeping, e.g. updating 14 to 11; so that table will end up as:
ruid rid(FK)
---------- ----------
1 10
2 10
3 12
4 10
5 10
6 11
7 11
How can I do that?
sql oracle oracle11g
add a comment |
I want to clean up my table:
rid(PK) rval
----------- ----------
10 test
11 Rtest
12 dummy
13 test
14 Rtest
to remove the duplicate values from column rval
, so I end up with:
rid(PK) rval
----------- ----------
10 test
11 Rtest
12 dummy
But I have another table with a foreign key relationship which uses the values I want to delete:
ruid rid(FK)
---------- ----------
1 10
2 10
3 12
4 13
5 13
6 14
7 14
so before I delete, I need to update that table to use the matching rid
that I'm keeping, e.g. updating 14 to 11; so that table will end up as:
ruid rid(FK)
---------- ----------
1 10
2 10
3 12
4 10
5 10
6 11
7 11
How can I do that?
sql oracle oracle11g
add a comment |
I want to clean up my table:
rid(PK) rval
----------- ----------
10 test
11 Rtest
12 dummy
13 test
14 Rtest
to remove the duplicate values from column rval
, so I end up with:
rid(PK) rval
----------- ----------
10 test
11 Rtest
12 dummy
But I have another table with a foreign key relationship which uses the values I want to delete:
ruid rid(FK)
---------- ----------
1 10
2 10
3 12
4 13
5 13
6 14
7 14
so before I delete, I need to update that table to use the matching rid
that I'm keeping, e.g. updating 14 to 11; so that table will end up as:
ruid rid(FK)
---------- ----------
1 10
2 10
3 12
4 10
5 10
6 11
7 11
How can I do that?
sql oracle oracle11g
I want to clean up my table:
rid(PK) rval
----------- ----------
10 test
11 Rtest
12 dummy
13 test
14 Rtest
to remove the duplicate values from column rval
, so I end up with:
rid(PK) rval
----------- ----------
10 test
11 Rtest
12 dummy
But I have another table with a foreign key relationship which uses the values I want to delete:
ruid rid(FK)
---------- ----------
1 10
2 10
3 12
4 13
5 13
6 14
7 14
so before I delete, I need to update that table to use the matching rid
that I'm keeping, e.g. updating 14 to 11; so that table will end up as:
ruid rid(FK)
---------- ----------
1 10
2 10
3 12
4 10
5 10
6 11
7 11
How can I do that?
sql oracle oracle11g
sql oracle oracle11g
edited Nov 14 '18 at 15:44
Alex Poole
133k6107181
133k6107181
asked Nov 14 '18 at 14:59
RGMRGM
66
66
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
You could use an analytic aggregate to get the lowest rid
for each rval
:
min(rid) over (partition by rval)
and use that in a subquery that joins the two tables (which I've imaginatively called t1
and t2
as you haven't given their real names) so you can see the lowest suitable rid
for each ruid
:
select t2.ruid, t2.rid, x.min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
join t2 on t2.rid = x.rid;
RUID RID MIN_RID
---------- ---------- ----------
1 10 10
2 10 10
3 12 12
4 13 10
5 13 10
6 14 11
7 14 11
You can then use that in a merge statement:
merge into t2
using (
select t2.ruid, t2.rid, x.min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
join t2 on t2.rid = x.rid
) y
on (t2.ruid = y.ruid)
when matched then update set t2.rid = y.min_rid
where t2.rid != y.min_rid;
4 rows merged.
select * from t2;
RUID RID
---------- ----------
1 10
2 10
3 12
4 10
5 10
6 11
7 11
Once you've done that you can remove the redundant PK values:
delete from t1
where exists (select * from t1 x where x.rval = t1.rval and x.rid < t1.rid);
2 rows deleted.
select * from t1;
RID RVAL
---------- -----
10 test
11 Rtest
12 dummy
Id ruid
is not unique, and there is no other unique key you can include in the statement, then you can't really use a merge - you can't refer to rid
in the on
clause as that's the column you're updating.
You could do a correlated update instead:
update t2
set rid = (
select min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
where x.rid = t2.rid
);
That will update every row; if you have a lot of data and/or a small proportion need to change then you can add a filter to only update those:
update t2
set rid = (
select min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
where x.rid = t2.rid
)
where rid != (
select min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
where x.rid = t2.rid
);
Thank you, it worked well!!! And thank you for formatting my question.
– RGM
Nov 14 '18 at 15:44
Will duplicate RUIDs always have the same RID?
– Alex Poole
Nov 15 '18 at 13:43
Duplicate RUID can have same and different both RID. for same RUID-RID I can use DISTINCT but if RID is not same, what to do in that case?
– RGM
Nov 15 '18 at 13:46
Can anyone suggest solution for duplicate RUID values?
– RGM
Nov 15 '18 at 14:26
@RGM - I've added a solution with a correlated update.
– Alex Poole
Nov 15 '18 at 15:06
|
show 3 more comments
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53303101%2fupdate-table-using-the-values-of-other-table%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You could use an analytic aggregate to get the lowest rid
for each rval
:
min(rid) over (partition by rval)
and use that in a subquery that joins the two tables (which I've imaginatively called t1
and t2
as you haven't given their real names) so you can see the lowest suitable rid
for each ruid
:
select t2.ruid, t2.rid, x.min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
join t2 on t2.rid = x.rid;
RUID RID MIN_RID
---------- ---------- ----------
1 10 10
2 10 10
3 12 12
4 13 10
5 13 10
6 14 11
7 14 11
You can then use that in a merge statement:
merge into t2
using (
select t2.ruid, t2.rid, x.min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
join t2 on t2.rid = x.rid
) y
on (t2.ruid = y.ruid)
when matched then update set t2.rid = y.min_rid
where t2.rid != y.min_rid;
4 rows merged.
select * from t2;
RUID RID
---------- ----------
1 10
2 10
3 12
4 10
5 10
6 11
7 11
Once you've done that you can remove the redundant PK values:
delete from t1
where exists (select * from t1 x where x.rval = t1.rval and x.rid < t1.rid);
2 rows deleted.
select * from t1;
RID RVAL
---------- -----
10 test
11 Rtest
12 dummy
Id ruid
is not unique, and there is no other unique key you can include in the statement, then you can't really use a merge - you can't refer to rid
in the on
clause as that's the column you're updating.
You could do a correlated update instead:
update t2
set rid = (
select min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
where x.rid = t2.rid
);
That will update every row; if you have a lot of data and/or a small proportion need to change then you can add a filter to only update those:
update t2
set rid = (
select min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
where x.rid = t2.rid
)
where rid != (
select min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
where x.rid = t2.rid
);
Thank you, it worked well!!! And thank you for formatting my question.
– RGM
Nov 14 '18 at 15:44
Will duplicate RUIDs always have the same RID?
– Alex Poole
Nov 15 '18 at 13:43
Duplicate RUID can have same and different both RID. for same RUID-RID I can use DISTINCT but if RID is not same, what to do in that case?
– RGM
Nov 15 '18 at 13:46
Can anyone suggest solution for duplicate RUID values?
– RGM
Nov 15 '18 at 14:26
@RGM - I've added a solution with a correlated update.
– Alex Poole
Nov 15 '18 at 15:06
|
show 3 more comments
You could use an analytic aggregate to get the lowest rid
for each rval
:
min(rid) over (partition by rval)
and use that in a subquery that joins the two tables (which I've imaginatively called t1
and t2
as you haven't given their real names) so you can see the lowest suitable rid
for each ruid
:
select t2.ruid, t2.rid, x.min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
join t2 on t2.rid = x.rid;
RUID RID MIN_RID
---------- ---------- ----------
1 10 10
2 10 10
3 12 12
4 13 10
5 13 10
6 14 11
7 14 11
You can then use that in a merge statement:
merge into t2
using (
select t2.ruid, t2.rid, x.min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
join t2 on t2.rid = x.rid
) y
on (t2.ruid = y.ruid)
when matched then update set t2.rid = y.min_rid
where t2.rid != y.min_rid;
4 rows merged.
select * from t2;
RUID RID
---------- ----------
1 10
2 10
3 12
4 10
5 10
6 11
7 11
Once you've done that you can remove the redundant PK values:
delete from t1
where exists (select * from t1 x where x.rval = t1.rval and x.rid < t1.rid);
2 rows deleted.
select * from t1;
RID RVAL
---------- -----
10 test
11 Rtest
12 dummy
Id ruid
is not unique, and there is no other unique key you can include in the statement, then you can't really use a merge - you can't refer to rid
in the on
clause as that's the column you're updating.
You could do a correlated update instead:
update t2
set rid = (
select min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
where x.rid = t2.rid
);
That will update every row; if you have a lot of data and/or a small proportion need to change then you can add a filter to only update those:
update t2
set rid = (
select min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
where x.rid = t2.rid
)
where rid != (
select min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
where x.rid = t2.rid
);
Thank you, it worked well!!! And thank you for formatting my question.
– RGM
Nov 14 '18 at 15:44
Will duplicate RUIDs always have the same RID?
– Alex Poole
Nov 15 '18 at 13:43
Duplicate RUID can have same and different both RID. for same RUID-RID I can use DISTINCT but if RID is not same, what to do in that case?
– RGM
Nov 15 '18 at 13:46
Can anyone suggest solution for duplicate RUID values?
– RGM
Nov 15 '18 at 14:26
@RGM - I've added a solution with a correlated update.
– Alex Poole
Nov 15 '18 at 15:06
|
show 3 more comments
You could use an analytic aggregate to get the lowest rid
for each rval
:
min(rid) over (partition by rval)
and use that in a subquery that joins the two tables (which I've imaginatively called t1
and t2
as you haven't given their real names) so you can see the lowest suitable rid
for each ruid
:
select t2.ruid, t2.rid, x.min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
join t2 on t2.rid = x.rid;
RUID RID MIN_RID
---------- ---------- ----------
1 10 10
2 10 10
3 12 12
4 13 10
5 13 10
6 14 11
7 14 11
You can then use that in a merge statement:
merge into t2
using (
select t2.ruid, t2.rid, x.min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
join t2 on t2.rid = x.rid
) y
on (t2.ruid = y.ruid)
when matched then update set t2.rid = y.min_rid
where t2.rid != y.min_rid;
4 rows merged.
select * from t2;
RUID RID
---------- ----------
1 10
2 10
3 12
4 10
5 10
6 11
7 11
Once you've done that you can remove the redundant PK values:
delete from t1
where exists (select * from t1 x where x.rval = t1.rval and x.rid < t1.rid);
2 rows deleted.
select * from t1;
RID RVAL
---------- -----
10 test
11 Rtest
12 dummy
Id ruid
is not unique, and there is no other unique key you can include in the statement, then you can't really use a merge - you can't refer to rid
in the on
clause as that's the column you're updating.
You could do a correlated update instead:
update t2
set rid = (
select min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
where x.rid = t2.rid
);
That will update every row; if you have a lot of data and/or a small proportion need to change then you can add a filter to only update those:
update t2
set rid = (
select min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
where x.rid = t2.rid
)
where rid != (
select min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
where x.rid = t2.rid
);
You could use an analytic aggregate to get the lowest rid
for each rval
:
min(rid) over (partition by rval)
and use that in a subquery that joins the two tables (which I've imaginatively called t1
and t2
as you haven't given their real names) so you can see the lowest suitable rid
for each ruid
:
select t2.ruid, t2.rid, x.min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
join t2 on t2.rid = x.rid;
RUID RID MIN_RID
---------- ---------- ----------
1 10 10
2 10 10
3 12 12
4 13 10
5 13 10
6 14 11
7 14 11
You can then use that in a merge statement:
merge into t2
using (
select t2.ruid, t2.rid, x.min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
join t2 on t2.rid = x.rid
) y
on (t2.ruid = y.ruid)
when matched then update set t2.rid = y.min_rid
where t2.rid != y.min_rid;
4 rows merged.
select * from t2;
RUID RID
---------- ----------
1 10
2 10
3 12
4 10
5 10
6 11
7 11
Once you've done that you can remove the redundant PK values:
delete from t1
where exists (select * from t1 x where x.rval = t1.rval and x.rid < t1.rid);
2 rows deleted.
select * from t1;
RID RVAL
---------- -----
10 test
11 Rtest
12 dummy
Id ruid
is not unique, and there is no other unique key you can include in the statement, then you can't really use a merge - you can't refer to rid
in the on
clause as that's the column you're updating.
You could do a correlated update instead:
update t2
set rid = (
select min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
where x.rid = t2.rid
);
That will update every row; if you have a lot of data and/or a small proportion need to change then you can add a filter to only update those:
update t2
set rid = (
select min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
where x.rid = t2.rid
)
where rid != (
select min_rid
from (
select rid, min(rid) over (partition by rval) as min_rid from t1
) x
where x.rid = t2.rid
);
edited Nov 15 '18 at 15:05
answered Nov 14 '18 at 15:36
Alex PooleAlex Poole
133k6107181
133k6107181
Thank you, it worked well!!! And thank you for formatting my question.
– RGM
Nov 14 '18 at 15:44
Will duplicate RUIDs always have the same RID?
– Alex Poole
Nov 15 '18 at 13:43
Duplicate RUID can have same and different both RID. for same RUID-RID I can use DISTINCT but if RID is not same, what to do in that case?
– RGM
Nov 15 '18 at 13:46
Can anyone suggest solution for duplicate RUID values?
– RGM
Nov 15 '18 at 14:26
@RGM - I've added a solution with a correlated update.
– Alex Poole
Nov 15 '18 at 15:06
|
show 3 more comments
Thank you, it worked well!!! And thank you for formatting my question.
– RGM
Nov 14 '18 at 15:44
Will duplicate RUIDs always have the same RID?
– Alex Poole
Nov 15 '18 at 13:43
Duplicate RUID can have same and different both RID. for same RUID-RID I can use DISTINCT but if RID is not same, what to do in that case?
– RGM
Nov 15 '18 at 13:46
Can anyone suggest solution for duplicate RUID values?
– RGM
Nov 15 '18 at 14:26
@RGM - I've added a solution with a correlated update.
– Alex Poole
Nov 15 '18 at 15:06
Thank you, it worked well!!! And thank you for formatting my question.
– RGM
Nov 14 '18 at 15:44
Thank you, it worked well!!! And thank you for formatting my question.
– RGM
Nov 14 '18 at 15:44
Will duplicate RUIDs always have the same RID?
– Alex Poole
Nov 15 '18 at 13:43
Will duplicate RUIDs always have the same RID?
– Alex Poole
Nov 15 '18 at 13:43
Duplicate RUID can have same and different both RID. for same RUID-RID I can use DISTINCT but if RID is not same, what to do in that case?
– RGM
Nov 15 '18 at 13:46
Duplicate RUID can have same and different both RID. for same RUID-RID I can use DISTINCT but if RID is not same, what to do in that case?
– RGM
Nov 15 '18 at 13:46
Can anyone suggest solution for duplicate RUID values?
– RGM
Nov 15 '18 at 14:26
Can anyone suggest solution for duplicate RUID values?
– RGM
Nov 15 '18 at 14:26
@RGM - I've added a solution with a correlated update.
– Alex Poole
Nov 15 '18 at 15:06
@RGM - I've added a solution with a correlated update.
– Alex Poole
Nov 15 '18 at 15:06
|
show 3 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53303101%2fupdate-table-using-the-values-of-other-table%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown