The best way would be to re-think your TxnTable and separate out the elements of
FormatString
into separate columns. If possible, don't do it in the first place, but if that is not possible you should create another temporary table along the lines of
create table #TxnTable2 (ID float, T nvarchar(10), CValue nvarchar(10), [Value] float, U date, GivenDate Date, Comment NVARCHAR(10))
If you have SQL Server 2016 or better then you can use the
STRING_SPLIT[
^] function along with the
REPLACE[
^] function (to remove the ;T=, CValue= and the quotation marks)
If you don't do that then your joins are going to end up looking like this ...
update a
set Comment = 'Matched'
from #TxnTable a
INNER JOIN #MasterTable b on b.CValue = LEFT(SUBSTRING(FormatString, CHARINDEX('CValue="', FormatString) + 8, LEN(formatstring)), CHARINDEX('"',SUBSTRING(FormatString, CHARINDEX('CValue="', FormatString) + 8, LEN(formatstring))) - 1)
where CHARINDEX('CValue="', FormatString) > 0
I've only done one of them because it upsets me to do more.
The update becomes trivial after that. You can either set everything to MisMatched and then correct the matching entries e.g.
update #TxnTable2 set Comment = 'MisMatched'
update a
set Comment = 'Matched'
from #TxnTable2 a
INNER JOIN #MasterTable b ON a.CValue =b.CValue
where a.[Value] between b.LimitFrom and b.LimitTo
and a.U = a.GivenDate
Or you can use a CASE statement e.g.
update a
set Comment = CASE WHEN a.[Value] between b.LimitFrom and b.LimitTo AND a.U = a.GivenDate
THEN 'Matched'
ELSE 'MisMatched' END
from #TxnTable2 a
INNER JOIN #MasterTable b ON a.CValue =b.CValue
It's largely down to personal preferences, I personally think the first version is easier to read.
Couple of other points,
- use
NULL
instead of 'NULL' when splitting out your values
- be consistent in your date formats and use ISO 8601 where possible. E.g. U="05/03/2021" should be either U="2021-03-05" or U="2021-05-03"