Reputation: 45
I have a huge table whereby i need to update the value on one column based on the values from 2 other columns, I extract the data and put it in other new #temp table where the format of the snippet data is as follows
DOC_GUID NAME Value Timestamp
-------- ---- ----- ---------
1111 V1 AC 1134
1111 V2 AB 1134
1112 V1 N 1234
1112 V2 AB 1234
1113 V1 AC 1334
1113 V2 N 1334
1114 V1 N 1434
1114 V2 N 1434
I need to update the values to become like this
DOC_GUID NAME Value Timestamp
-------- ---- ----- ---------
1111 V1 AC 1134
1111 V2 AC 1134
1112 V1 AB 1234
1112 V2 AB 1234
1113 V1 AC 1334
1113 V2 AC 1334
1114 V1 N 1434
1114 V2 N 1434
I tried to write out the logic as follows, but it cant be executed at all
UPDATE #temp
SET Value = CASE WHEN (A.DOC_GUID = B.DOC_GUID
FROM #temp A inner join #temp B
ON A.Value= 'AC' OR
B.Value = 'AC')
THEN 'AC'
WHEN (A.DOC_GUID = B.DOC_GUID
FROM #temp A inner join #temp B
ON A.Value= 'AB' OR
B.Value = 'AB')
THEN 'AB' END
Upvotes: 0
Views: 117
Reputation: 37367
DDL:
declare @tbl table (DOC_GUID int, NAME varchar(3), Value varchar(3), Timestamp int );
insert into @tbl values
(1111,'V1','AC',1134),
(1111,'V2','AB',1134),
(1112,'V1','AB',1234),
(1112,'V2','N',1234),
(1113,'V1','AC',1334),
(1113,'V2','N',1334),
(1114,'V1','N',1434),
(1114,'V2','N',1434);
Update query:
update t1 set t1.Value = t2.Value
from @tbl t1 join (
select *,
-- here I use case statement to make AC come before AB
row_number() over (partition by DOC_GUID order by case when [Value] = 'AC' then 'AA' else [Value] end) rn
from @tbl
) t2 on t1.DOC_GUID = t2.DOC_GUID
where t2.rn = 1
Upvotes: 2
Reputation: 1269773
You can do this using window function and an updatable CTE:
with toupdate as (
select t.*,
max(case when seqnum = 1 then value end) over (partition by doc_guid) as use_value
from (select t.*,
row_number() over (partition by doc_guid order by priority) as seqnum
from t left join
(values ('AC', 1),
('AB', 2),
('N', 3)
) v(value, priority)
on v.value = t.value
) t
)
update toupdate
set value = use_value
where use_value <> value;
This approach has two major advantages.
First, it is quite simple to change the priorities because these are embedded in the VALUES()
clause.
Second, the outer where
clause only updates the rows that need to be updated.
This should also have good performance characteristics.
Upvotes: 1
Reputation: 521249
We can try using CASE
along with an EXISTS
clause:
UPDATE t1
SET Value = CASE WHEN EXISTS (SELECT 1 FROM #temp t2
WHERE t1.DOC_GUID = t2.DOC_GUID AND
t2.Value = 'AC')
THEN 'AC'
WHEN EXISTS (SELECT 1 FROM #temp t2
WHERE t1.DOC_GUID = t2.DOC_GUID AND
t2.Value = 'AB')
THEN 'AB'
ELSE 'N' END
FROM #temp t1;
Upvotes: 0