Copy column from another table with 'where' - sql

I have two tables: Table1 and Table2
Table1
id name value source
----------- ----------- ----- ------------
1 a 4 10
2 b 5 10
3 c 6 11
Table2
set text
----------- -----------
7 h
8 g
I want to copy the 'value' column to Table2 from Table1, where table1.source = 10
set text value
----------- ----------- ---------
7 h 4
8 g 5
I tried this:
ALTER TABLE Table2 ADD value INT NOT NULL DEFAULT 0
UPDATE tb2
SET tb1.value = tb2.value
from Table2 tb2
JOIN Table1 tb1
ON tb1.source=10
it has given me this :
id name value
----------- ----------- ---------
7 h 4
8 g 4
It's updating Table2 rows with only the first source value from Table1.
What am I doing wrong ?
Thanks in advance!

If you are using sQL server ,use the below query to update the table2.
Note that the script is specific to the given sample data.
ALTER TABLE Table2
ADD value INT NOT NULL DEFAULT 0
GO
WITH cte_data
as
(SELECT ROW_NUMBER() OVER(ORDER BY [set])RNo,*
FROM Table2 )
UPDATE c
SET c.Value=t.Value
FROM cte_data c
JOIN Table1 t on c.RNo=t.Id
WHERE t.Source=10

Maybe you can try this:
insert into table2 (value) select (value) from table1 where table1.source = 10
Just add new "value" field in "table2" and try this approach.

You need a row number for the join. I would advise putting this in both tables:
WITH toupdate AS (
SELECT tb1.*,
ROW_NUMBER() OVER (PARTITION BY source ORDER BY id) as seqnum
FROM table1 tb1
)
UPDATE toupdate
SET tb1.value = tb2.value
FROM toupdate tb1 JOIN
(SELECT tb2.*,
ROW_NUMBER() OVER (ORDER BY set) as seqnum
FROM table2 tb2
) tb2
ON tb2.seqnum = tb1.seqnum
WHERE tb1.source = 10;

Related

SQL - Delete specific set of raw in a table using another table

Tabel 1 :
ID1
ID2
ID3
MainID
Location
1
A
X
1AX
VIC
2
B
Y
2BY
SYD
3
C
W
3CW
TAS
4
D
Z
4DZ
TAS
Tabel 2 :
SALESID
QTY
AMT
DIFF
1AX
1
100
2
2BY
2
0
3
3CW
3
5
4DZ
3
12
2
Ignore other fields, I need to delete all raws in Tabel 1 where AMT in Tabel 2 has zero or no value for the SALESID.
For example, after the query, only raws containing 1AX & 4DZ should be remain in Tabel 1.
this can be done by subquery
get all MainID from table2 where amt is 0 or null
delete all rows that equal to previous fetched MainID
delete from table1 where MainID in (
select SALESID from table2 where AMT <=0 or AMT is null
)
You can use exists:
delete from table1
where exists (select 1
from table2 t2
where table1.mainid = t2.salesid and
(t2.amt = 0 or t2.amt is null)
);
Thinking an INNER JOIN would be much faster on larger data sets. Something like this:
DELETE
T1
FROM
Table1 T1
INNER JOIN
Table2 T2 ON T2.SalesID = T1.MainID
WHERE
IsNull(T2.Amt,0) = 0

Update table with different values from a different table which is grouped

I have a oracle table called table1 that has a foreign key from table2.
table2 has 2 columns: id, name
table2.name has a lot of duplicates that need to be sorted out, so I grouped table2 by name and kept only 1 id for each name.
However, table1.table2_id uses a lot of the duplicated fields.
How can I change all the table1.table2_id fields so that there are no duplicate names?
Currently:
table1:
id
blabla
table2_id
1
row
1001
2
row
1002
3
row
1003
4
row
1004
5
row
1004
6
row
1005
table2:
id
name
1001
Bob
1002
Bob
1003
Bob
1004
Jack
1005
Jack
Desired Result:
table1:
id
blabla
table2_id
1
row
1001
2
row
1001
3
row
1001
4
row
1004
5
row
1004
6
row
1004
table2:
id
name
1001
Bob
1004
Jack
So imo, I would need to:
update all table1.table2_id to top 1 table2.id grouped by name
delete duplicate rows from table2
And as there are thousands of duplicate fields in table2, I cannot use case for this..
The solution I am trying returns 1 id for each name, but I am failing at the part where I can update the table.
update table1 d
set d.table2_id =
(select
b.id
from table2 b
where b.name in (select min(id) keep(dense_rank first order by id) id
, name
from table2
group by name)
order by b.id ASC
)
where d.table2_id in ( SELECT b.id FROM table2 b WHERE b.name in (select min(id) keep(dense_rank first order by id) id
, name
from table2
group by name));
Please help :)
Here are syntactically correct Oracle statements
update table1 t1
set t1.table2_id = (
select new_id
from (
select id, min(id) over (partition by name) new_id
from table2
) d
where d.id = t1.table2_id
);
delete from table2
where id not in (
select min(id) from table2 group by name
);
The analytic function min(id) over (partition by name) is used here so that you can have all original ids together with their new ids (the min ids from the set where the name is the same).
here is one way:
update table1 d
set d.table2_id = x.id_tokeep
from
(
select name , id , min(id) over (partition by name ) as id_tokeep
from table2
) x
where x.id = d.table2_id
delete from table2
where id not in ( select min(id) from table2 group by name)

i want update one column in sql on basis of id i.e. insert id values in the my new column

i want update one column in sql on basis of id i.e. insert id values in the my new column
tb1
id1 name1
1 A
2 B
3 C
TB2
ID2 name id1 name1
1 X 1 null
2 Y 2 null
3 Z 1 null
what i wanted update TB2 name1 column on the basis of id1
Update TB2 SET TB2.name1 = tb1.name1 FROM tb1 ,TB2 WHERE tb1.id1 = TB2.id1
try this code in MS SQl
You could try update with join
update t2 set t2.nam1 = t1.name1 from tb2 t2
join tb1 t1 on t1.id1 = t2.id1

update query result not reflecting in table

I have two tables test1 and test2. What I need is, I would like to update one column in the table test2 with data from the table test1. My query is
UPDATE test2 t2
SET t2.name = (SELECT t1.name
FROM test1 t1
WHERE t1.id = t2.mob)
WHERE t2.mob IN (SELECT t1.id
FROM test1 t1
WHERE t1.id = t2.mob)
It's showing 3 Rows updated , But It's not reflecting in my table. My reference. Is there any issue in my query. Or what should I do alternately.
It wold be easier to use merge statement:
/* test tables */
SQL> create table test1(id1, name1) as
2 select level
3 , dbms_random.string('l', 7)
4 from dual
5 connect by level <= 5;
Table created
SQL> create table test2(id1, name1) as
2 select level
3 , cast(null as varchar2(11))
4 from dual
5 connect by level <= 5;
Table created
Tables' contents:
SQL> column name1 format a10;
SQL> select * from test1;
ID1 NAME1
---------- ----------
1 ouegwac
2 bptytsz
3 xwpnuqi
4 jrbxeza
5 hlckwvk
SQL> select * from test2;
ID1 NAME1
---------- ----------
1 NULL
2 NULL
3 NULL
4 NULL
5 NULL
Update test2.name1 column with data from test1.name1 column:
SQL> merge into test2 t
2 using test1 q
3 on (q.id1 = t.id1)
4 when matched then
5 update set t.name1 = q.name1
6 ;
5 rows merged
SQL> select * from test2;
ID1 NAME1
---------- ----------
1 ouegwac
2 bptytsz
3 xwpnuqi
4 jrbxeza
5 hlckwvk
UPDATE
(SELECT test2.name as t2, test1.name as t1
FROM test2
INNER JOIN test1
ON test2.MOB= test1.ID
) t
SET t.t2= t.t1
The WHERE part in your query is absolutely unnecessary because it always evaluates to TRUE. So the correct one to update all rows in t2 is:
UPDATE test2 t2
SET t2.name = (SELECT t1.name
FROM test1 t1
WHERE t1.id = t2.mob)
Also in PL/SQL Developer transactions are not commited automatically by default. You have to manually commit it by pressing that green arrow on the panel.

SQL query help

Sorry for posting this question again. I rephrased my question a little bit.
I am trying to write a query to return rows from Table-A where multiple rows found in Table-B with STATUS = 1 for each CID column from Table-A.
So in this example CID 100 has two records found in Table-B and STATUS = 1. So I want to write a query to return this row from Table-A. I know this is a weird table design. Please help.
Here are the tables with sample data.
Table-A
-----------------------------------------
AID Name CID
---------------------------------------
10 test1 100
12 test1 100
13 test2 101
14 test2 101
15 test3 102
Table-B
------------------------------------
bID AID status
-----------------------------------
1 10 1
2 12 1
3 14 1
4 15 1
Try this query:
SELECT TableA.CID
FROM TableA
JOIN TableB ON TableA.AID = TableB.AID
WHERE TableB.status = 1
GROUP BY TableA.CID
HAVING COUNT(*) > 1
It returns 100 for your example data.
Something like this?
select aid,
status
from (select aid,
count(*) as cnt
from tableA
group by aid) as aggregated
left join tableB on tableB.aid = aggregated.aid
where aggregated.cnt > 1
If your using SQL:
WITH tableBView AS
(
SELECT AID AS xxxAID
FROM [Table-B]
WHERE status = 1
GROUP BY AID
HAVING COUNT(*) > 0
)
SELECT *
FROM [Table-A]
WHERE EXISTS (SELECT * FROM tableBView WHERE xxxAID = AID)
SELECT *
FROM Table-A a
WHERE a.CID IN
(
SELECT a.CID FROM Table-A a JOIN Table-B b USING (AID)
GROUP BY a.CID
WHERE b.status = 1
HAVING count(*) > 1
)
This is a very verbose way to do it.
Selects all columns from Table-A on rows where AID match between Table-A and Table-B and more than one row with the same CID exists in Table-A:
(Btw, I wouldn't use "-" in your table/column names. Use "_" instead.)
select
derived_table.AID,
derived_table.Name,
derived_table.CID
from
(select
table_A.AID,
table_A.Name,
table_A.CID,
count(table_A.CID) c
from
Table_A
inner join Table_B on (Table_A.AID = table_B.AID)
group by table_A.CID
) derived_table
where
c > 1