In Oracle is there way to select a data set and use it for update like in the Merge statement.
I'm looking for something like
USING
(
SELECT a, b, c FROM t
)
UPDATE t1
SET t1.x = t.a,
t1.y = t.b;
It sounds like you just want to
UPDATE t1
SET (x, y) = (SELECT a, b
FROM t
WHERE t.some_column = t1.some_column);
If you only want to update rows in T1 if there is a matching row in T
UPDATE t1
SET (x, y) = (SELECT a, b
FROM t
WHERE t.some_column = t1.some_column)
WHERE EXISTS (
SELECT 1
FROM t
WHERE t.some_column = t1.some_column );
If your SELECT from T returns a single row, you can omit the WHERE clause that joins the two tables.
Related
I encountered following problem:
I have a long query (let's call it query "Z" ) that includes lots of joins and subqueries. It ouputs two columns:
A: item
B: Integer attribute, range guaranteed to be 1-10
I want to join from table X items (column A) that are not present as output of query Z and give them an arbitrary attribute value 10 (column B).
I tried creating subquery with inner subquery uisng not exists but that requires copying my original query inside and takes a lot of time (I didn't even manage to execute it).
Any suggestions? Thanks
It's not entirely clear from your question but I think you mean table X is a superset of the records from query Z. If so, a simple outer join should give you the result you want:
select coalesce(z.a, x.a) as a
, coalesce(z.b, 10) as b
from x
left outer join ( your query ) z
on z.a = x.a
If X is not a superset of Z then you should try a FULL OUTER JOIN instead.
I have assumed that column A works as a UID for the query Z and the table X. If this is not the case you'll need to tweak the above statement, or edit your question to include more details.
According to your comments , one possibility is to first make a union of the results of your "Z" query and then another select with the addition of only selecting the MIN() of your column B.
So it would look something along the lines of :
SELECT A , MIN(B) FROM
(
(QUERY Z) AS Z
union
(SELECT ITEM as A, 10 as B FROM X)
)
GROUP BY A
I did it similarily to what #Ancaron posted.
SELECT A, B FROM Z
UNION ALL
SELECT A, '10' FROM X
WHERE NOT EXISTS
(
select Z.A
from Z
WHERE Z.A=X.A
)
I am new to Oracle. I am trying to update the values of a table with the values from a SELECT DISTINCT statement using the MERGE INTO method. I want to update the values for a table based on what is in the USING table conditionally.
A quick diagram of what I am essentially going for is
MERGE
INTO update_table ut
USING
(SELECT DISTINCT
t1.column_1
,t2.column_2
FROM table_1 t1
INNER JOIN table_2 t2
ON t1.foreign_key = t2.primary_key) st
ON (ut.pk = st.column_1)
WHEN MATCH UPATE
SET(ut.update_column = st.column_2
WHERE st.column_1 = 1
AND st.column_2 = 1
,ut.update_column = st.column_2
WHERE st.column_1 = 2
AND st.column_2 = 2);
However, when I do so I get the INVALID COLUMN SPECIFICATION error on the line where I use SET. How can I work around this to successfully update the table, preferably in ANSI standard?
You can include the conditions that you have added in where clause in the selected column list in using clause itself. Like This. (Not tested. Your conditions in where clause were not appropriate)
MERGE
INTO update_table ut
USING (SELECT DISTINCT
t1.column_1 ,
CASE
WHEN t1.column_1 = 1
AND t2.column_2 = 1
THEN t2.column_1
WHEN t1.column_1 = 2
AND t2.column_2 = 2
THEN t2.column_2
END column_2
FROM
table_1 t1
INNER JOIN table_2 t2 ON t1.foreign_key = t2.primary_key
) st
ON (ut.pk = st.column_1)
WHEN MATCHED THEN
UPDATE SET ut.update_column = st.column_2 ;
When i execute the following query, i get the message like
Ora-01427 single-row subquery returns more than one row
I am trying to update "City" column in Table A From another table.
How would I do this?
table A: Name, PER_code(it also has duplicated value or null), city, PD_code
table B: Name, PER_code(No duplicated value,Maybe null), city, Postal_code
The update statement:
UPDATE A
SET (A.city) =
(SELECT B.city
FROM B
INNER JOIN A
ON A.per_code=B.per_code
WHERE A.per_code is not null)
Since there are duplicate values but you select only one field, you modify your query from
UPDATE A SET (A.city) = (SELECT B.city FROM B INNER JOIN A ON
A.per_code=B.per_code WHERE A.per_code is not null)
to
UPDATE A SET (A.city) = (SELECT DISTINCT B.city FROM B INNER JOIN A ON
A.per_code=B.per_code WHERE A.per_code is not null)
The distinct operator will allow you to keep a single value if it's duplicated in the table B. If there are multiple distinct values, you will have to look at your data and make a decision about which value should be used in the other table.
You can also try MERGE INTO selecting DISTINCT records.
MERGE INTO A d
USING
( SELECT DISTINCT per_code, city FROM B ) s
ON ( s.per_code = d.per_code )
WHEN MATCHED THEN UPDATE SET d.City = s.City
WHERE d.per_code IS NOT NULL;
I think you intend a correlated subquery:
UPDATE A
SET city = (SELECT B.city
FROM B
WHERE A.per_code = B.per_code
)
WHERE A.per_code is not null;
EDIT:
The above should work given the constraints in the original question. If it does not, it is easily adaptable:
UPDATE A
SET city = (SELECT B.city
FROM B
WHERE A.per_code = B.per_code AND rownum = 1
)
WHERE A.per_code is not null;
I want to update a column prtnum and revlvl in table invdtl based on value from select statment, here is the code
update invdtl set invdtl.prtnum = usr_prtmst_xref.prtnum,invdtl.revlvl =
usr_prtmst_xref.colnam ([select
invdtl.prtnum,usr_prtmst_xref.prtnum AS
crossref,invdtl.revlvl,aremst.arecod,aremst.fwiflg from invdtl
join usr_prtmst_xref
on usr_prtmst_xref.prtnum = usr_prtmst_xref.prtnum
join invsub
join invlod
join locmst
join aremst
on aremst.arecod = locmst.arecod
and aremst.wh_id = locmst.wh_id
on locmst.stoloc = invlod.stoloc
and locmst.wh_id = invlod.wh_id
on invlod.lodnum = invsub.lodnum
on invsub.subnum = invdtl.subnum where aremst.arecod = 'EXPR' or
aremst.fwiflg = '1' and rownum <2])
I want to copy two values prtnum and revlvl that are returned by select statement but there is some syntax issue.
There are a bunch of errors here:
The syntax for a multi-column update is basically
update blah
set ( col1, col2 ) = ( select x, y
from
...
)
The syntax for multiple joins is basically
from table1 t1
join table2 t2
on t1.col = t2.col
join table3 t2 on
t2.col = ...
Get ride of "[" and "]"
The predicate rownum<2 is probably to get around the message you received, something like "single row sub-query returns more than 1
row" Which this predicate "fixes" that problem, you are just getting
the first random row; probably not what you want. You probably need to
correlate the sub-query with the update
I would fix these basic syntax errors and try again.
Im trying to copy some field from a table to other, I want to do iy by using insert with a subquery like this:
insert into sed_reporte_generico
(srg_usuario,
srg_nombres,
srg_ape_paterno,
srg_ape_materno,
srg_objetivo,
srg_peso_ob,
srg_calf_ob)
values
(
(select us.su_st_usuario, us.su_st_nombres, us.su_st_ap_paterno, us.su_st_ap_materno, ob.soc_st_descripcion, ob.soc_nr_peso,ob.soc_nr_calificacion
from sed_objetivo ob, sed_usuarios us, sed_evaluacion ev
where ob.se_evaluacion_pk = ev.se_evaluacion_pk and ev.su_colaborador_fk = us.su_usuarios_pk)
);
but I got this error:
01427. 00000 - "single-row subquery returns more than one row"
any idea how should I do this?
Thanks,
Think you got to choose between
insert into table (a, b, c) VALUES(1, 2, 3)
and
insert into table (a, b, c)
(SELECT x, y, z from table2)
You can have VALUES and SELECT mixed only (as pointed by an anomyous horse)
when your select query returns only one column and one row !
By the way, use JOIN... to Join your tables (use of the WHERE clauses to join tables is rather a bad habit) :
INSERT INTO sed_reporte_generico
(srg_usuario,
srg_nombres,
srg_ape_paterno,
srg_ape_materno,
srg_objetivo,
srg_peso_ob,
srg_calf_ob)
(select us.su_st_usuario, us.su_st_nombres, us.su_st_ap_paterno, us.su_st_ap_materno, ob.soc_st_descripcion, ob.soc_nr_peso,ob.soc_nr_calificacion
FROM sed_objetivo ob
JOIN sed_evaluacion ev ON ob.se_evaluacion_pk = ev.se_evaluacion_pk
JOIN sed_usuarios us on ev.su_colaborador_fk = us.su_usuarios_pk)
);