What I’m trying to accomplish is select from a table and return all the records where the Type matches one of the parameter types. Remove duplicates with the primaryType being the record of choice if found, if not then a single record from one of the other type arguments. The order doesn’t matter for the other types although it would be nice (can pick @secondType or @thirdType). This is a POC project so if I need to add or change things to make it easier/faster I’m open to ideas!
NOTE: UUID and PARTID are alphanumeric. DECLARE @primaryType varchar(32) = 'diamond'; DECLARE @secondType varchar(32) = 'gold'; DECLARE @thirdType varchar(32) = 'nickel'; SettingName Type PARTID UUID ---------------------------------------- Alpha diamond 123 123 <== Returned because the primaryType takes precedence Alpha - g gold 123 321 <== Not returned because it would be a duplicate, primaryType wins Charlie diamond 456 456 <== Returned; no duplicate partid and is in type list. Delta - c copper 789 789 <== Not returned becuase it's not in type list Echo - g gold 987 987 <== Returned because no duplicate partid and is in type list
Desired result…
Alpha diamond 123 123 <== Returned because the primaryType takes precedence Charlie diamond 456 456 <== Returned no duplicate partid and is in type list. Echo - g gold 987 987 <== Returned because no duplicate partid and is in type list
I’ve tried something like the code below as well as other code but just can’t seem to nail it down.
SELECT * from ( SELECT SettingName, Type, PARTID, UUID ,row_number() over (partition by PARTID order by Type ) idx FROM Settings WHERE (Type = @primaryType OR Type = @secondType OR Type = @thirdType) ) a where idx = 1
Where the code above gets hung up is the order by Type can return the wrong result because the @primaryType may be further down the list when sorted. Which would return @secondType or @thirdType depending on the sorted result.
Advertisement
Answer
You are almost there, just use the @Type values in the over(order by) clause to create custom ordering/precedence.
declare @t table ( id int identity, SettingName varchar(50), Type varchar(50), PARTID varchar(50), UUID varchar(50) ); insert into @t(SettingName, Type, PARTID, UUID) values ('Alpha', 'diamond', '123', '123'), --<== Returned because the primaryType takes precedence ('Alpha - g', 'gold', '123', '321'), --<== Not returned because it would be a duplicate, primaryType wins ('Charlie', 'diamond', '456', '456'), --<== Returned; no duplicate partid and is in type list. ('Delta - c', 'copper', '789', '789'), -- <== Not returned becuase it's not in type list ('Echo - g', 'gold', '987', '987'); DECLARE @primaryType varchar(32) = 'diamond'; DECLARE @secondType varchar(32) = 'gold'; DECLARE @thirdType varchar(32) = 'nickel'; select * from ( select *, row_number() over(partition by PARTID order by case Type when @primaryType then 1 when @secondType then 2 when @thirdType then 3 else 4 end, len(Type), id /*id as final tie-breaker*/) as rownum from @t where Type in (@primaryType, @secondType, @thirdType) ) as a --where a.rownum = 1