Update column of Table B based on column of Table A - sql

I have a huge stored procedure and I am trying to optimize it .
I have a temporary table A , with column Id.
I have a main table B with columns Id & a boolean field Test
For all Id's in Table A , I need to make the Test = 1 in Table B.
example :
A
Id
--
1
2
3
I need to get table B as follows.
I already have the Id field in Table B , I only need to update the
Test Column
B
Id Test
-- ----
1 1
2 1
3 1
4
5
6
I am currently looping through Table A using a while loop and for each Id
I am updating the Test column in Table B .
WHILE (1 = 1)
BEGIN
-- Exit loop if no more Transactions
IF ##ROWCOUNT = 0 BREAK;
Update [B]
set Test = 1
where Id = (SELECT TOP 1 Id
FROM #B
WHERE Id > #Id1
ORDER BY Id)
END
PS : #Id1 is the input parameter of the stored procedure.
I cannot think of any other efficient way of doing it, but
my query is taking a lot of time to run..
Please let me know if there is a better way of doing the same thing.

This is pretty straight forward.
UPDATE [B]
SET [TEST] = 1
FROM [B] INNER JOIN [A]
ON [A].ID = [B].ID

Another alternative:
UPDATE b SET test = 1
FROM dbo.TableB AS b
WHERE EXISTS (SELECT 1 FROM dbo.TableA WHERE ID = b.ID);

You don't need to loop for this, just join those tables
UPDATE B
SET B.Test = 1
FROM TableB B
INNER JOIN TableA A
ON A.Id = B.ID
Here is an sqlfiddle with a live demo.

You can use in to find the records to update:
update b
set Test = 1
where Id in (select Id from #A)
Another alternative is to join the tables:
update x
set Test = 1
from b as x
inner join #A as a on a.id = x.id

If I'm understanding your question correctly, all you need to do is join A and B.
UPDATE TableB SET test = 1
FROM TableB b
INNER JOIN TableA a ON a.id = b.id
WHERE b.ID > #Id1
Basically you're looking to update everywhere where TableA and TableB intersect.
http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

Related

Update fields with data from a second table

I have a database in PostgreSQL and I'm having some problems updating some values, let me explain.
I have three tables.
Table A:
id | itemID | Value
Table B:
Name | Value
Table C:
itemID | Name
I need to update the value field on table A with the value from table B where the itemId from the tables A and C are equal.
I don't really know how to explain, please ask me anything so I can explain it better
You need a join in the UPDATE statement:
update tablea
set "Value" = b."Value"
from tableb b inner join tablec c
on c.name = b.name
where c."itemID" = tablea."itemID";
See the demo.
You can use Update statement with a Common Table Expression, and bring the results directly by adding returning clause at the end.
with t0 as
(
select c.itemID , b.value
from tableC c
left join tableB b on b.name = c.name
)
update tableA a
set value = t0.value
from t0
where a.itemID = t0.itemID
returning a.*;
Demo

select sql query to merge results

I have a table old_data and a table new_data. I want to write a select statement that gives me
Rows in old_data stay there
New rows in new_data get added to old_data
unique key is id so rows with id in new_data should update existing ones in old_data
I need to write a select statement that would give me old_data updated with new data and new data added to it.
Example:
Table a:
id count
1 2
2 19
3 4
Table b:
id count
2 22
5 7
I need a SELECT statement that gives me
id count
1 2
2 22
3 4
5 7
Based on your desired results:
SELECT
*
FROM
[TableB] AS B
UNION ALL
SELECT
*
FROM
[TableA] AS A
WHERE
A.id NOT IN (SELECT id FROM [TableB])
I think this would work pretty neatly with COALESCE:
SELECT a.id, COALESCE(b.count, a.count)
FROM a
FULL OUTER JOIN b
ON a.id = b.id
Note - if your RDBMS does not contain COALESCE, you can write out the function using CASE as follows:
SELECT a.id,
CASE WHEN b.count IS NULL THEN a.count
ELSE b.count END AS count
FROM ...
You can write a FULL OUTER JOIN as follows:
SELECT *
FROM a
LEFT JOIN b
ON a.id = b.id
UNION ALL
SELECT *
FROM b
LEFT a
ON b.id = a.id
You have to use UPSERT to update old data and add new data in Old_data table and select all rows from Old_data. Check following and let me know what you think about this query
UPDATE [old_data]
SET [count] = B.[count]
FROM [old_data] AS A
INNER JOIN [new_Data] AS B
ON A.[id] = B.[id]
INSERT INTO [old_data]
([id]
,[count])
SELECT A.[id]
,A.[count]
FROM [new_Data] AS A
LEFT JOIN [old_data] AS B
ON A.[id] = B.[id]
WHERE B.[id] IS NULL
SELECT *
FROM [old_data]

SQL Query is updating with NULL values

I am using Oracle and I am trying to update a table(A) with data from another table(B). Not every field in B has a value so I have a number of NULL entries. When I run the update it says 6000 rows updated. Now there are 6000 rows in table B, however for this query only 14 have data in. When I select count(*) from both tables for this value they both return 14 rows each. Why is it reporting that 6000 rows have been updated?
UPDATE
table1 A
SET
phone_work = (
SELECT B.phone_work
FROM table2 B
WHERE B.id = A.applicant_id)
WHERE EXISTS (
SELECT 1
FROM table2 B
WHERE B.id = A.applicant_id);
I have also tried the following and I get the same result:
UPDATE
table1 A
SET
phone_work = (
SELECT B.phone_work
FROM table2 B
WHERE B.id = A.applicant_id
AND B.phone_work is not null
)
WHERE EXISTS (
SELECT 1
FROM table2 B
WHERE B.id = A.applicant_id);
Why is it reporting the update of 6000 rows? When I change the fields but use the same syntax it reports updating of the exact number of rows I expect e.g. a count of table B has 86 entries in the NAME field and it reports 86 rows updated. It seems that with the phone_work field I am getting every null value being counted as an update.
Perhaps you want to check for the non-NULL value in the exists:
UPDATE table1 A
SET phone_work = (SELECT B.phone_work
FROM table2 B
WHERE B.id = A.applicant_id
)
WHERE EXISTS (SELECT 1
FROM table2 B
WHERE B.id = A.applicant_id AND B.phone_work IS NOT NULL
);
Try this:
UPDATE
(
SELECT A.phone_work Aphone, B.phone_work Bphone
FROM table2 B, table1 A
WHERE B.id = A.applicant_id AND B.phone_work IS NOT NULL
)
SET
Aphone = Bphone;
Source: Oracle SQL: Update a table with data from another table

Searching Unique Id in Multiple Tables

I have a Scenario where i am required to search unique id in Mutiple tables and assign a level based on where it exist.
Table Hierarchy
TableA
TableB
TableC
Table B holds primary key of table A and Table C holds the Primary of TableB
I need to have a function that takes Id as parameter and Searches that Id in this Table Hierarchy and Return Level i-e If it exist in TableA Level should be One. If it exists in TableB Level should be 2 and if it's in TableC then level should be 3
Here's one way:
SELECT CASE WHEN EXISTS(SELECT 1 FROM TableC WHERE id = #id) THEN '3'
WHEN EXISTS(SELECT 1 FROM TableB WHERE id = #id) THEN '2'
WHEN EXISTS(SELECT 1 FROM TableA WHERE id = #id) THEN 'One'
END AS "Level"
Assuming you want to return the highest level, 3 being the highest for TableC, then something like this should work using the CASE statement:
SELECT
CASE
WHEN C.Id IS NOT NULL THEN 3
WHEN B.Id IS NOT NULL THEN 2
WHEN A.Id IS NOT NULL THEN 1
END as Level
FROM (SELECT #Id as Id) H
LEFT JOIN TableA A ON H.Id = A.Id
LEFT JOIN TableB B ON H.Id = B.Id
LEFT JOIN TableC C ON H.Id = C.Id
Where #Id is the Id of the value you are searching for, for example SELECT 1 as Id.
Good luck.
You need a query that looks like this:
SELECT 1 FROM TableA WHERE id = {0}
UNION ALL
SELECT 2 FROM TableB WHERE id = {0}
UNION ALL
SELECT 3 FROM TableC WHERE id = {0}
The advantage to this over "WHEN" statements is that a) I don't like WHEN statements, and b) if a key exists in multiple tables, this returns a record for each, giving you the opportunity to build program logic around handling that case.

SQL Server: IF EXISTS ; ELSE

I have a tableA:
ID value
1 100
2 101
2 444
3 501
Also TableB
ID Code
1
2
Now I want to populate col = code of table B if there exists ID = 2 in tableA. for multiple values , get max value.
else populate it with '123'. Now here is what I used:
if exists (select MAX(value) from #A where id = 2)
BEGIN
update #B
set code = (select MAX(value) from #A where id = 2)
from #A
END
ELSE
update #B
set code = 123
from #B
I am sure there is some problem in BEGIN;END or in IF EXIST;ELSE.
Basically I want to by-pass the else part if select statement in IF-part exist and vice- versa. For example if select statement of IF=part is:
(select MAX(value) from #A where id = 4)
It should just populate 123, coz ID = 4 do not exist !
EDIT
I want to add the reason that your IF statement seems to not work. When you do an EXISTS on an aggregate, it's always going to be true. It returns a value even if the ID doesn't exist. Sure, it's NULL, but its returning it. Instead, do this:
if exists(select 1 from table where id = 4)
and you'll get to the ELSE portion of your IF statement.
Now, here's a better, set-based solution:
update b
set code = isnull(a.value, 123)
from #b b
left join (select id, max(value) from #a group by id) a
on b.id = a.id
where
b.id = yourid
This has the benefit of being able to run on the entire table rather than individual ids.
Try this:
Update TableB Set
Code = Coalesce(
(Select Max(Value)
From TableA
Where Id = b.Id), 123)
From TableB b
I know its been a while since the original post but I like using CTE's and this worked for me:
WITH cte_table_a
AS
(
SELECT [id] [id]
, MAX([value]) [value]
FROM table_a
GROUP BY [id]
)
UPDATE table_b
SET table_b.code = CASE WHEN cte_table_a.[value] IS NOT NULL THEN cte_table_a.[value] ELSE 124 END
FROM table_b
LEFT OUTER JOIN cte_table_a
ON table_b.id = cte_table_a.id