DECLARE @delimiter NVARCHAR(MAX) = '||' DECLARE @null_replacement NVARCHAR(MAX) = '^^' ; WITH source_data AS ( SELECT 0 AS hk,'MA1' AS ma_attribute, null col_a, null col_b UNION all SELECT 0 AS hk,'MA2' AS ma_attribute, NULL col_a, NULL col_b UNION all SELECT 0 AS hk,'MA2' AS ma_attribute, NULL col_a, NULL col_b UNION all SELECT 0 AS hk,'MA3' AS ma_attribute, null col_a, null col_b UNION all SELECT 1 AS hk,'MA2' AS ma_attribute, 'col_a' col_a, NULL col_b UNION all SELECT 1 AS hk,'MA3' AS ma_attribute, null col_a, null col_b ),h1 AS ( SELECT hk, STRING_AGG( REPLACE( CONCAT(ISNULL(col_a,'^^'),'||',ISNULL(col_b,'^^')), '^^||^^', '^^' ),'||') WITHIN GROUP (ORDER BY ma_attribute) hdiffstr, LEFT(REPLICATE(CAST(@null_replacement+@delimiter AS varchar(max)),COUNT(*)),(LEN(@null_replacement+@delimiter)*COUNT(*))-LEN(@delimiter)) AS all_null FROM source_data GROUP BY hk ) SELECT h.*, CASE WHEN hdiffstr = all_null then CAST(REPLICATE(0x0,16) AS BINARY(16)) ELSE HASHBYTES('md5',h.hdiffstr) END hdiff FROM h1 h