Olá,
Creio que resolvi isto com o uso do Case.
Desta forma meu script ficou assim:
update dbo.Tabela
set Coluna1 = case when Tabela2.Coluna1 <> '' then Tabela2.Coluna1 else Tabela.Coluna1 end,
Coluna2 = case when Tabela2.Coluna2 <> '' then Tabela2.Coluna2 else Tabela.Coluna2 end,
Coluna3 = case when Tabela2.Coluna3 <> '' then Tabela2.Coluna3 else Tabela.Coluna3 end,
CPF = Tabela2.CPF
from (
Select w.ID,w.Coluna1,w.Coluna2,w.Coluna3,w.CPF
from dbo.Tabela j inner join dbo.Tabela3 w
on j.ID=w.ID
where j.Coluna1<>w.Coluna1 or j.Coluna2<>w.Coluna2 or j.Coluna3 <> w.Coluna3 or (j.CPF<>w.CPF and (w.CPF <> '' and j.CPF = ''))
) Tabela2
where dbo.Tabela.ID = Tabela2.ID
Desta forma continuo buscando as diferenças com o where contendo or, mas ao fazer o update com select, uso o case para ver se o valor retornado tem valor, caso não tenha uso o else e mantenho o valor da coluna final.
Valeuuuus
[Gosto de compartilhar problemas com soluções que encontro no dia de trabalho]