How to Update column values of T1 from T2 using one condition? - sql

I tried this query and i get this msg SQL Error: ORA-00933: SQL command not properly ended ,but i can't see where the problem realy is ?
update T1 set T1.name=T2.name from Table1 T1
inner join Table2 T2
on T1.id=T2.id where T2.id in (select id from Table2 group by id having count(entity)=1);

Your statement is not valid Oracle syntax.
You have two common options.
Option #1: use a correlated subquery in your UPDATE...
update table t1
set t1.name = ( SELECT t2.name
FROM table2 t2
WHERE t2.id = t1.id
AND t2.id IN ( SELECT t2a.id
FROM table2 t2a
GROUP BY t2a.id
HAVING COUNT(t2a.entity) = 1 )
)
where exists ( SELECT 'x'
FROM table2 t2
WHERE t2.id = t1.id
AND t2.id IN ( SELECT t2a.id
FROM table2 t2a
GROUP BY t2a.id
HAVING COUNT(t2a.entity) = 1 )
;
Option #2: (my preference) use a MERGE statement:
merge into table1 t
using ( SELECT t2.id,
t2.name,
COUNT(t2.entity) OVER ( PARTITION BY t2.id ) entity_count
FROM table2 t2
) u
ON ( t.id = u.id AND u.entity_count = 1 )
WHEN MATCHED THEN UPDATE SET t.name = u.name;
I usually test SQL before I post it, but no time today. So, there might be syntax errors in the above.

I would phrase the update as:
update table t1
set t1.name = (select t2.name
from table2 t2
where t2.id = t1.id and rownum = 1
)
where (select count(t2.entity)
from table2 t2
where t2.id = t1.id
) = 1;

I'm not sure if I understood the data context. I created an example where ID's aren't UNIQUE
create table T1 ( name varchar2(55), id number(4,0), entity number(2,0));
create table T2 ( name varchar2(55), id number(4,0), entity number(2,0));
insert into T1 (name, id, entity) values ('T1name1', 1, 1);
insert into T1 (name, id, entity) values ('T1name2', 2, 1);
insert into T1 (name, id, entity) values ('T1name3', 3, 3);
insert into T1 (name, id, entity) values ('T1name4', 4, 4);
insert into T2 (name, id, entity) values ('T2name1', 1, 1);
insert into T2 (name, id, entity) values ('T2name2', 2, 1);
insert into T2 (name, id, entity) values ('T2name3', 3, 3);
insert into T2 (name, id, entity) values ('T2name4', 3, 1);
update T1 set name =
nvl(
( select name
from T2
where T2.id = T1.id
and exists
( select 'x'
from T2 table2
where table2.id = T2.id
group by id
having count(entity) = 1)
)
,T1.name)
In this context, just T1.id = 1 and T1.id = 2 will be updated (T2.id = 3 has count(entity) = 2)

Related

Update Table T1 column to be the quotient of two queries each leveraging ID from T1

I am trying to update a column to be the quotient of two queries that count records in two other tables for each ID in T1.
It seems like this should work (but doesn't):
Update T1 Set COLUMN1 = (select count(*) from T2 where T2.ID = T1.ID) / (select count(*) from T3 where T3.ID = T1.ID)
Edit to add data sample and expected output:
T1 is like:
ID
COLUMN1
0
1
T2 and T3 are both like this, where ID can be repeated:
ID
UID
0
00
1
01
1
02
1
03
The expected output is T1 should be:
ID
COLUMN1
0
quotient of count of records in t2 and t3 where id is 0
1
quotient of count of records in t2 and t3 where id is 1
Maybe this would work?
Update T1
Set COLUMN1 = 1.0 * (select count(*) from T2 where T2.ID = T1.ID) /
(select count(*) from T3 where T3.ID = T1.ID)
Multiplying by 1.0 to force the result to be a float.
Dont know what data to mimic on T3 table and as per question mentioned it would be like T2 (assumed same ) and build query. Take a look
WITH t1 AS (
SELECT
*
FROM
VALUES
(0, ''),(1, '') v(ID, COLUMN1)
),
t2 as (
SELECT
*
FROM
VALUES
(0, 00),(1, 01),(1, 02),(1, 03) v(ID, UID)
),
t3 as (
SELECT
*
FROM
VALUES
(0, 00),(1, 01),(1, 02) v(ID, UID)
),
t1_t2_count as (
select
count(*) as cnt
from
T1,
T2
where
T2.ID = T1.ID
),
t1_t3_count as (
select
count(*) as cnt
from
T1,
T3
where
T3.ID = T1.ID
)
Select
t1_t2_count.cnt t1t2_cnt,
t1_t3_count.cnt as t1t3_cnt,
div0(t1t2_cnt,t1t3_cnt) result
from
t1_t2_count,t1_t3_count;

Update values in one table with values in another table

I have table1 and table2. They have the same columns and the column ID is the one that i can use to connect the tables.
How can i run foreach statment that will update row Name in table1 with the value for column Name in table2?
I need this so i can fix the column Name in Table1 because it is incorect , and the good values for it are in table2
I tried using a single update statement but it takes forever to execute because both tables are with over 600 000 rows
update
table1 t1
set
(
t1.name
) = (
select
t2.name
from
table2 t2
where
t2.id = t1.id
and
rownum = 1
)
where exists (
select
null
from
table2 t2
where
t2.id = t1.id
);
For this query:
update table1 t1
set t1.name = (select t2.name from table2 t2 where t2.id = t1.id and rownum = 1)
where exists (select 1
from table2 t2
where t2.id = t1.id
);
You want an index on table2(id, name).
A simple inner join should work this.
UPDATE T1
SET T1.NAME = T2.NAME
FROM MyTable T1
INNER JOIN MyOtherTable T2
ON T1.ID = T2.ID

SQL: select from t1 all rows for which there's no corresponding in t2

Let's say I have a table t1 with only one column: id, and I have a table t2 with two columns: id and Memo. I need to select those id from t1, for which there is NO row in t2 that satisfies both of the following two conditions t1.id = t2.id and t2.Memo = 'myText'. How can I do that? I have tried using join, but that selects row that do satisfy some conditions, whereas I need the opposite.
SELECT *
FROM t1
WHERE NOT EXISTS (SELECT 1
FROM t2
WHERE t2.id = t1.id
AND t2.Memo = 'myText')
One way to do it is using LEFT JOIN:
select id
from t1
left join t2
on t1.id = t2.id and t2.Memo = 'myText'
where t2.id is null
I'm not good in understanding your question:
You mean those t1.id EXISTS in t2 BUT the corresponding t2.Memo <> 'myText'?
SELECT t1.id FROM t1 JOIN t2
ON t1.id = t2.id
HAVING t1.id NOT IN (SELECT id FROM t2 WHERE Memo = 'myText');
Or all t1.id either NOT EXISTS in t2 or EXISTS but Memo <> 'myText'?
SELECT id FROM t1 WHERE id NOT IN (SELECT id FROM t2 WHERE Memo = 'myText');

update one table with data from another using the common key

update one table with data from another using the common key
create table table1 (
id varchar2(4),
name varchar2(10),
desc_ varchar2(10)
)
create table table2 (
id varchar2(4),
id_new varchar2(4)
)
insert into table1 values('1111', 'a', 'abc')
insert into table1 values('2222', 'b', 'def')
insert into table1 values('3333', 'c', 'ghi')
insert into table1 values('4444', 'd', 'jkl')
insert into table2 values('1111', '8080')
insert into table2 values('2222', '9090')
merge into table1 t1
using (select * from table2) t2
on (t1.id = t2.id)
when matched then update set t1.id = t2.id_new
error: ORA-27432: step does not exist for chain .
This should work:
update table1 t1
set id = coalesce((
select id_new
from table2 t2
where t1.id = t2.id), id);
SQL Fiddle Demo
Here's an alternative approach with merge:
merge into table1 t1
using (select * from table2) t2
on (1 = 1)
when matched then update set t1.id = t2.id_new where t1.id = t2.id
More Fiddle
Probably best speed you'll obtain using:
merge into table1 t1
using (select t1.rowid rw, t2.id_new
from table2 t2
join table1 on (table1.id = t2.id)
) s
on t1.rowid = s.rowid
when matched then update set t1.id = s.id_new;
However it depends on optimizer(previous answers may have a good behavior if CBO intuits your desire)

How do I fix "The name 'X' is not permitted in this context"?

INSERT INTO dbo.VehiclesCategories ( VehicleId, CategoryId )
VALUES ( t1.ID , t2.ID)
SELECT t1.ID, t2.ID
FROM dbo.Vehicle t1
inner JOIN dbo.VehicleCategory t2 ON t1.Category = t2.Name
In the above SQL, I want to insert two values into a M:M join table. The SELECT statement works fine and I get the desired results. The INSERT statement throws the following error:
Msg 128, Level 15, State 1, Line 2
The name "t1.ID" is not permitted in this context. Valid expressions are constants, constant expressions, and (in some contexts) variables. Column names are not permitted.
How do I insert the two values (t1.ID and t2.ID) into the table?
That's because in the context of the INSERT, t1 and t2, don't exist.
If you combine those two queries, I think it will do exactly what you want:
INSERT INTO dbo.VehiclesCategories ( VehicleId, CategoryId )
SELECT t1.ID, t2.ID
FROM dbo.Vehicle t1
inner JOIN dbo.VehicleCategory t2 ON t1.Category = t2.Name
Do not include the VALUES (t1.ID, t2.ID) part at all.
Try this
INSERT dbo.VehiclesCategories ( VehicleId, CategoryId )
SELECT t1.ID, t2.ID
FROM dbo.Vehicle t1
JOIN dbo.VehicleCategory t2 ON t1.Category = t2.Name
just delete VALUES ( t1.ID , t2.ID) from insert into