sqlserver How to write a codition based on min rank

sqlserver How to write a codition based on min rank

could you please let me know how to write a codition based on min rank,

Create table TableA1 (PatID int, blockName varchar(20), RankID int)


insert into TableA1 values (123, 'Cancer', 5)
insert into TableA1 values (235, 'Hearts', 6)
insert into TableA1 values (345, 'Child' ,1)
insert into TableA1 values (123, 'OutPatient', 3)
insert into TableA1 values (567, 'OutPatient', 4)
insert into TableA1 values (789, 'Inbound' , 7)
insert into TableA1 values (567, 'OutPatient', 3)
insert into TableA1 values (678, 'Cancer', 5)
insert into TableA1 values (789, 'Hearts', 6)
insert into TableA1 values (789, 'KidneySpl', 9)
insert into TableA1 values (345, 'OutPatient', 3)

select * from TableA1 order by 1


Create table TableB1 (PatID int, ModelId int )

insert into TableB1 values (123,114346)
insert into TableB1 values (235,226554)
insert into TableB1 values (345,336544)
insert into TableB1 values (567,446789)
insert into TableB1 values (678,558987)
insert into TableB1 values (789,667998)


select * from TableB1 order by 1

--Joining
select a.*, b.ModelID from TableA1 A inner join TableB1 B
on a.PatID = b.PatID
order by 1,3

Required outcome is based on the RankID . So if for the same PatID that appears more times in TableA1, the ModelID (from TableB) goes to the record with highest rankID.

expected Results will be

WITH R AS (
SELECT
    PatID,
    blockName,
    RankID,
 ROW_NUMBER() OVER(PARTITION BY PatID ORDER BY RankID DESC) AS rn
FROM
 TableA1
)
SELECT
    A.PatID,
    A.blockName,
    A.RankID,
 B.ModelID
FROM
 R AS A
 LEFT OUTER JOIN
 TableB1 AS B
 ON A.PatID = B.PatID
 AND A.rn = 1
ORDER BY
 A.PatID,
 A.RankID
GO

We do not know the highest rank per PatID in advance (if by the highest you mean the lower then change the ORDER BY subclause to ASC order), so if we enumerate rows for each PatID in descending order by the rank then the highest will always be 1, and that is the extra filter on the join. I used an outer join in order to not exclude lower ranks but if you do not want to see them in the final result then use an INNER join.

I guess you will have no duplicates by RankID for the same PatID otherwise you will have to use RANK / DENSE_RANK or break the tie using another column.

  • Back aarticle:
  • Next aarticle: No
  • Copyright © 2007-2012 www.chuibin.com Chuibin Copyright