I accidentally updated all records for table2 data column custno with value ='33'
Now I need to recover all the column data for custno from table1 to table2 (without affecting the other data).
Note that there are no primary keys on either of the tables. It also seems several IDs are repeating.
table1 may have the same ID more than once, and all IDs need to be populated with the same date value as found in table2 for the same ID.
Any help is greatly appreciated.
-------------------so here is the actual scenario updated :-------------------------
table 1 (previous table in good state)
id col1 col2 col3 col4 colN custno
1 1 dhruv joshi 3 2 12
1 1 alpha beta 3 2 12
1 1 ebta alpha 3 2 12
1 1 dhruv joshi 3 2 11
1 1 alpha beta 3 2 11
1 1 ebta alpha 3 2 10
table 2 ( accidently updated the custno =33 for all the records )
id col1 col2 col3 col4 colN custno
1 1 dhruv joshi 3 2 33
1 1 alpha beta 3 2 33
1 1 ebta alpha 3 2 33
1 1 dhruv joshi 3 2 33
1 1 alpha beta 3 2 33
1 1 ebta alpha 3 2 33
now i have to recover this table 2 column (custno) exactly as table1 without touching any other columns.
I hope this will clear the scenario now.
After updating this query , it gives unexpected result.
UPDATE t2
SET t2.custno = t1.custno
FROM table1 AS t1
JOIN table2 AS t2
ON t1.ID = t2.ID
AND t1.col1 =t2.col1
AND t1.col2 =t2.col2
AND t1.col3 =t2.col3
AND t1.colN =t2.colN
The unexpected result being
id col1 col2 col3 col4 colN custno
1 1 dhruv joshi 3 2 12
1 1 alpha beta 3 2 12
1 1 ebta alpha 3 2 12
1 1 dhruv joshi 3 2 12
1 1 alpha beta 3 2 12
1 1 ebta alpha 3 2 12
In case you don't have any unique column in the table, you have to apply on condition on multiple columns (of the table) so that it makes the row uniquely identifiable for update.
Example if your table is defined as table1[ id int, col1 int, col2 varchar(100), col3 varchar(100), col4 int,..., colN int, customerNo int) and there is no unique column.
Then to update it on basis of customerNo only will pose problems.
The way is to identify multiple(or all) columns to make it more unique during update like this.
UPDATE t2
SET t2.custno = t1.custno
FROM table1 AS t1
JOIN table2 AS t2
ON t1.ID = t2.ID
AND t1.col1 =t2.col1
AND t1.col2 =t2.col2
AND t1.col3 =t2.col3
..
AND t1.colN =t2.colN
Fiddle link http://sqlfiddle.com/#!6/ff9895/2
PS: This was intended to be a comment to question but because it is too big, I am putting it as answer
I was also wondering if you had a back of the table why don't you simply restore it into original table like
-- This deletes all rows
DELETE FROM table2 WHERE Id IS NOT NULL
-- This inserts all rows from table1(the original table) into table2 to make it like table1
INSERT INTO Table2
SELECT * FROM Table1
I dont know much about but if tables are same structure you can try this:-
Update t2 set t2.custno = t1.custno
from
(
select ROW_NUMBER() over (order by col1 asc)as RANK, * from table_1
)t1
Inner join
(
select ROW_NUMBER() over (order by col1 asc)as RANK, * from table_2
)t2
on t1.RANK = t2.RANK
Related
I have 4 tables:
table1
ID PNTID col3 col4 col5
123 456 y y 0
444 456 y y 0
900 878 n n 1
table 2
ID TID col3 col4 col5 col6
123 999 777 888 0 x
456 111 988 - - -
444 123 988 - - -
table 2- after update
ID TID col3 col4 col5 col6
123 111 777 888 0 x
456 111 988 - - -
444 111 988 - - -
table 3 -update or insert
TID col2 col3 col4 col5
111 988 x x x
table 4 -update or insert
TID col2 col3 col4 col5
111 988 x x x
I am trying to achieve:
-> Check the col3,col4,col5 if there values matching like Y,Y and 0 then get the values of ID from table 2 that matches PNTID of table1 such as TID , col3..
->Update table 2 wherein ID has same PNTID table1 such as ID : 123, 444
->In table 3,Check TID is there or not if its there then update col2 with the value of table2.col3 of PNTID(ID- col in table 2) else insert a new row as columns in table 2(TID,col,col2,col3...)
Similarly , Need to update or insert table 4 with respect to table 2.
I am trying to build the subqueries .like to get the matched rows of table 1 and 2 the proceed further.
SELECT *
FROM dbo.table tb1
INNER JOIN table2 tb2
ON tb1.ID = tb2.ID
WHERE tb1.col3 = 'Y'
AND tb1.col4 = 'Y'
AND tb1.col5 = 0
this gives me matched rows but how to fetch values and insert into other tables record by record as table 1 and 2 have many records.
can anyone help me on this?
Thanks!
UPDATE <table to update t1>INNER JOIN <table with inner join t2>
ON t1 = t2
SET t1.id =t2.id
WHERE <condition>
the above code is for updation on fly
if this does not work try using triggers
I have two tables and below is the example
Table1
KEY BEGIN_DATE TOTAL_RATE
1 1974-01-01 3
1 1981-01-01 3
1 1983-01-01 4
1 1985-07-01 4
1 1989-10-01 7
1 1990-07-01 10
1 1997-10-01 11
1 2008-04-01 13
TABLE2
KEY END_DATE RATE_REDUCED
1 1989-09-30 2
1 1997-09-31 4
From Table 2 if key matches then we need to reduce TOTALRATE from Table 1
with RATEREDUCED in Table 2 where BEGINDATE > ENDDATE and it should happen
till the end of table 2 ENDDATE
EXPECTED RESULTS/UPDATE TO TABLE 1:
RESULT
KEY BEGIN_DATE NEW_RATE
1 1974-01-01 3
1 1981-01-01 3
1 1983-01-01 4
1 1985-07-01 4
1 1989-10-01 7 - 2 = 5 (Date is Greater than 1989-09-30)
1 1990-07-01 10 - 2 = 8 (Date is Greater than 1989-09-30)
1 1997-10-01 11 - 2 - 4 = 5 (Date is Greater than two dates)
1 2008-04-01 13 - 2 - 4 = 7 (Date is Greater than two dates)
I have many keys in table two and table one.
Is update with join possible
Thanks in advance
Similar to Gordon's, here we use use an Update in a CROSS APPLY. This approach will only update the records which match the criteria
Update Table1 Set TOTAL_RATE=TOTAL_Rate-B.Adj
From Table1 A
Cross Apply (
Select Adj=sum(RATE_REDUCED)
From Table2
Where END_DATE<=A.BEGIN_DATE and [Key]=A.[Key]
) B
Where B.Adj is not NULL
The Updated Table1 Looks like this now
KEY BEGIN_DATE TOTAL_RATE
1 1974-01-01 3
1 1981-01-01 3
1 1983-01-01 4
1 1985-07-01 4
1 1989-10-01 5
1 1990-07-01 8
1 1997-10-01 5
1 2008-04-01 7
This looks like a good application of outer apply:
select t1.*,
(t1.total_rate - coalesce(t2.rate_reduced, 0)) as total_rate
from table1 t1 outer apply
(select sum(t2.rate_reduced) as rate_reduced
from table2 t2
where t1.begin_date > t2.end_date and
t1.key = t2.key
) t2;
EDIT:
If you want to turn this into an update, that is easy:
update t1
set total_rate = (t1.total_rate - coalesce(t2.rate_reduced, 0))
from table1 t1 outer apply
(select sum(t2.rate_reduced) as rate_reduced
from table2 t2
where t1.begin_date > t2.end_date and
t1.key = t2.key
) t2;
I'm not sure about the difference in performance between using a join or using a subquery. Maybe you can try out the solutions mentioned in the other answers and compare it to a (simpler?) subquery approach:
update table1
set total_rate = total_rate -
(select COALESCE(sum(new_rate),0)
from table2
where begin_date > end_date
and table1.key = table2.key)
I have to tables :
Table1
--------------------------------
ID VAL1 DATE1
--------------------------------
1 1 20/03/2015
2 null null
3 1 10/01/2015
4 0 12/02/2015
5 null null
Table2
--------------------------------
ID VAL2 DATE1
--------------------------------
1 N 02/06/2015
1 N 01/08/2015
2 null null
3 O 05/04/2016
3 O 02/02/2015
4 O 01/07/2015
5 O 03/02/2015
5 N 10/01/2014
5 O 12/04/2015
I want to update :
column VAL1 (of Table1) with '0', if VAL2 (of Table2) is equal to 'O'
column DATE1 (of Table1) with the earliest DATE2 (of Table2) for each ID (here my problem)
(This two tables are not so simple, it's just for illustration, they can be joined with the ID column).
Here my code :
UPDATE Table1 t1
SET t1.VAL1 = '0',
t1.DATE1 = (select min(t2.DATE2) --To take the first DATE for each ID where VAL2='O' (not working fine)
FROM Table2 t2, Table1 t1
WHERE trim(t2.ID) = trim(t1.ID)
AND VAL2='O')
WHERE EXISTS (SELECT NULL
FROM Table2 t2
WHERE trim(t2.ID) = trim(t1.ID)
AND t2.Table2 = 'O')
AND VAL1<>'0'; --(for doing the update only if VAL1 not already equal to 0)
The expected result is :
Table1
--------------------------------
ID VAL1 DATE1
--------------------------------
1 1 20/03/2015
2 null null
3 0 02/02/2015
4 0 01/07/2015
5 0 10/01/2014
The result I get is :
Table1
--------------------------------
ID VAL1 DATE1
--------------------------------
1 1 20/03/2015
2 null null
3 0 10/01/2014
4 0 10/01/2014
5 0 10/01/2014
My problem is that the DATE1 is always updated with the same date, regardless of the ID.
You shouldn't have a second reference to table1 in the first subquery; that is losing the correlation between the subquery and the outer query. If you run the subquery on its own it will always find the lowest date in table2 for any ID that has val2='O' in table1, which is 10/01/2014. (Except your sample data isn't consistent; that's actually N so won't be considered - your current and expected results don't match the data you showed, but you said it isn't real). Every row eligible to be updated runs that same subquery and gets that same value.
You need to maintain the correlation between the outer query and the subquery, so the subquery should use the outer table1 for its join, just like the second subquery already does:
UPDATE Table1 t1
SET t1.VAL1 = '0',
t1.DATE1 = (select min(t2.DATE2)
FROM Table2 t2
WHERE trim(t2.ID) = trim(t1.ID)
AND VAL2='O')
WHERE EXISTS (SELECT NULL
FROM Table2 t2
WHERE trim(t2.ID) = trim(t1.ID)
AND t2.Val2 = 'O')
AND VAL1<>'0';
You can use this UPDATE statement.
UPDATE TABLE1 T1
SET T1.VAL1 = '0',
T1.DATE1 = (SELECT MIN(T2.DATE2)
FROM TABLE2 T2
WHERE TRIM(T2.ID) = TRIM(T1.ID)
AND T2.VAL2='O')
WHERE T1.ID IN (SELECT T2.ID FROM TABLE2 T2 WHERE T2.VAL2='O')
Hope it will help you.
MYSQL Solution
Hope this MySql syntax also works with ORACLE.
The issue with the SQL is that it only consider the records with VAL2=='O' when calculating the earliest date. So the last record have the date as shown in table below. Record "5 N 10/01/2014" is not considered.
UPDATE Table1, (SELECT * FROM (SELECT * FROM table2 WHERE VAL2='O' ORDER BY ID, DATE1) X GROUP BY X.ID) T2
SET Table1.DATE1=T2.DATE1, Table1.VAL1=0
WHERE Table1.ID=T2.ID
..
Table1
--------------------------------
ID VAL1 DATE1
--------------------------------
1 1 20/03/2015
2 null null
3 0 02/02/2015
4 0 01/07/2015
5 0 **03/02/2015**
Tested on MySql 5.6.14
I have two tables e.g:
Table1ID Name visitAreaCode
1 test1 003
2 test2 003
3 test5 004
Table2ID Table1ID BingID
1 2 2
Table3 BingID
1 1
2 2
3 2
If visitAreaCode from table1 are not present in table2 (by Table1ID) then the query should add all of them. In table2 BindID 1 does not exists so when executing this query BingID 1 should be linked with all the areacode starts with 003. Table 2 should then look like:
Table2ID Table1ID BingID
1 3 2
2 1 1
3 2 1
I can use IF NOT EXISTS(SELECT * FROM ... but this will only add one record not all the records.
If i am correctly understanding you question then try this:
INSERT INTO Table2 (Table1ID, BingID)
SELECT t1.Table1ID, t3.BingID FROM Table1ID as t1, Table3 as t3
WHERE
NOT EXISTS (
SELECT * FROM Table2 as t2
WHERE t2.Table1ID = t1.Table1ID AND t2.BingID = t3.BingID
)
Assuming that Table2.Table2ID is autoincrement
I m looking to a way to insert into database Table T1 from T2 (append operation_
Table 1 : dbo.t1
col1 col2
---- -----
1 ABC
2 ABCr
3 ABCs
4 ABCd
Table 2 : dbo.t2
col1 col2
---- -----
7 ABCe
8 ABCy
Now , table 1 becomes
col1 col2
---- -----
1 ABC
2 ABCr
3 ABCs
4 ABCd
7 ABCe
8 ABCy
SQL query , I m using is:
select *
into dbo.t1
from dbo.t2
I know it would way too simple using #temp table.
I m looking for a way so that I just append the rows from T2 to T1 and keep performance as well. The existing rows of T1 is not touch at all.
Any help would be helpful.
Thanks !!!
Does this answer your question? It will insert all records from Table2 to the end of Table1 (and not touch existing records in Table1)
insert into Table1 (col1, col2) (select col1, col2 from Table2)