i using merge statement insert/update records in database.
my source table contains 3 columns used identify if record needs inserted or updated. problem arises in on clause – target table , source table joined using 3 columns there numerous variations on how joined. (see below example)
i know , / or operators used achieve become messy , difficult maintain. wondering if there more efficient way?
an example of code below:
merge target_table t using (select @param1, @param2, @param3) s (col1, col2, col3) on (t.col1 = s.col1 , t.col2 = s.col2 , t.col3 = s.col3) or (t.col1 = s.col2 , t.col2 = s.col1 , t.col3 = s.col3) when matched […update…] when not matched […insert…]
thanks in advance!
you build source table differently, rather using or
build combinations before merge condition. e.g.
declare @param1 int = 1, @param2 int = 2, @param3 int = 3; params ( select pvalue, pnumber (values (@param1, 1), (@param2, 2), (@param3, 3)) p (pvalue, pnumber) ) select col1 = p1.pvalue, col2 = p2.pvalue, col3 = p3.pvalue params p1 inner join params p2 on p2.pnumber not in (p1.pnumber) inner join params p3 on p3.pnumber not in (p1.pnumber, p2.pnumber);
this gives 6 combinations (with each join making sure not re-using same parameter):
col1 col2 col3 ------------------ 2 3 1 3 2 1 1 3 2 3 1 2 1 2 3 2 1 3
so merge
condition become simpler:
with params ( select pvalue, pnumber (values (@param1, 1), (@param2, 2), (@param3, 3)) p (pvalue, pnumber) ), sourcetable ( select col1 = p1.pvalue, col2 = p2.pvalue, col3 = p3.pvalue params p1 inner join params p2 on p2.pnumber not in (p1.pnumber) inner join params p3 on p3.pnumber not in (p1.pnumber, p2.pnumber) ) merge target_table t using sourcetable s on t.col1 = s.col1 , t.col2 = s.col2 , t.col3 = s.col3 when matched […update…] when not matched […insert…];
this makes easier add further parameters, 4th parameter require row in cte params
, rather whole new set of or
conditions
declare @param1 int = 1, @param2 int = 2, @param3 int = 3, @param4 int = 4; params ( select pvalue, pnumber (values (@param1, 1), (@param2, 2), (@param3, 3), (@param4, 4)) p (pvalue, pnumber) ) select col1 = p1.pvalue, col2 = p2.pvalue, col3 = p3.pvalue params p1 inner join params p2 on p2.pnumber not in (p1.pnumber) inner join params p3 on p3.pnumber not in (p1.pnumber, p2.pnumber);
which gives 24 combinations, without code.
Comments
Post a Comment