Sélectionner une requête en fonction de la priorité d'une string donnée

J'ai une table

ID|Expense|Name 1|1000|John 1|1000|Roger 1|1000|Megan 2|500|Sally 2|500|John 3|700|Jen 3|700|Mike 

Je veux grouper par identification et dépense mais veux juste une rangée. Aussi, je voudrais donner la preference à John en sélectionnant et n'importe quelle rangée random si John n'est pas présent. (pour id = 3 tout Jen ou Mike est acceptable)

Résultat souhaité:

 ID|Expense|Name 1|1000|John 2|500|John 3|700|Jen 

J'ai essayé d'utiliser Rank , mais je ne suis pas capable de me différencier des ids sans John.

S'il vous plaît Aide

Merci!

Cela peut être fait avec row_number avec la priorité en utilisant l'expression case .

 select id,expense,name from ( select t.*,row_number() over(partition by id order by case when name='John' then 1 else 2 end) as rnum from tbl t ) t where rnum=1 

Une autre option sans champ supplémentaire utilise la clause WITH TIES

Exemple

 Declare @YourTable Table ([ID] int,[Expense] int,[Name] varchar(50)) Insert Into @YourTable Values (1,1000,'John') ,(1,1000,'Roger') ,(1,1000,'Megan') ,(2,500,'Sally') ,(2,500,'John') ,(3,700,'Jen') ,(3,700,'Mike') Select Top 1 with ties * from @YourTable Order By Row_Number() over (Partition By ID,Expense Order By NullIf(Name,'John')) 

Résultats

 ID Expense Name 1 1000 John 2 500 John 3 700 Jen