T-SQL renvoie une ligne si une autre ligne n'existe pas

Disons que j'ai cette table (ceci est simplifié, bien sûr il y a d'autres colonnes):

CompanyID (int) ContactName (varchar(50)) ContactType (char(1)) 

avec les valeurs:

 CompanyID | ContactName | ContactType ----------------------------------------------- 1 | John Doe | A 1 | Jane Smith | B 2 | Ralph Jones | B 3 | Dick Grayson | A 

Ce que je veux, ce sont toutes les entresockets où il y a un ContactType = 'A', à less qu'il n'y ait pas de ContactType = 'A' renvoyer le ContactType = 'B'. Donc, dans cet exemple, je veux:

 1, John Doe (because he's a ContactType A) 2, Ralph Jones (because Company #2 doesn't have a ContactType A) 3, Dick Grayson (because he's a ContactType A) 

Je ne peux pas simplement dire «A ou B» parce qu'une entreprise peut avoir les deux.

Voici ce que j'ai essayé (et échoué)

 use MyFancyDatabase drop table #TypeA drop table #TypeB drop table #TypeAB create table #TypeA(ownerkey int, ContactName varchar(200), ContactType char(1)) insert #TypeA Select ownerkey, ContactName, ContactType from address where ContactType = 'A' and CancelDate is null create table #TypeB(ownerkey int, ContactName varchar(200), ContactType char(1)) insert #TypeB Select ownerkey, ContactName, ContactType from address where ContactType = 'B' and CancelDate is null create table #TypeAB(ownerkey int, ContactName varchar(200), ContactType char(1)) insert #TypeAB select * from #TypeA except select * from #TypeB 

Je suppose qu'en anglais c'est "A, mais s'il n'y a pas de A, alors prenez B."

Aucune suggestion?

 SELECT a.OwnerKey, a.CompanyName, Case WHEN a.ContactType IS NULL THEN b.ContactType ELSE a.ContactType END AS ContactType FROM #TypeA a LEFT JOIN #TypeB b on a.OwnerKey = b.OwnerKey 

Je pense que cela devrait marcher pour vous.

 with SortedResults as ( select CompanyID , ContactName , ContactType , ROW_NUMBER() over (partition by CompanyID order by ContactType) as RowNum from ThisTable ) select * from SortedResults where RowNum = 1 

Essayez ceci SQL

 Select t1.CompanyID , ContactName = IIF(t1.ContactType='A',t1.ContactName,t2.ContactName) ContactType = IIF(t1.ContactType='A','A',t2.ContactType) FROM address as t1 left join address as t2 on t1.CompanyID = t2.CompanyID AND t1.ContactName = t2.ContactName AND (t1.ContactType <> t2.ContactType) 

Si vous avez plus de type que A ou B et que vous voulez juste A et B append ceci sur le point où

 WHERE (t1.ContactType = 'A' OR t1.ContactType = 'B') AND (t2.ContactType = 'A' OR t2.ContactType = 'B') 

Les colonnes de votre table définie ne semblent pas correspondre à celles de votre exemple de requête. Je suppose que OwnerKey est le même que CompanyID?

Si c'est le cas, et que vous conservez la majeure partie du rest de votre code, le dernier choix doit être:

 select * from #TypeA union all select * from #TypeB where not exists ( select * from #TypeA where #TypeA.ownerkey = #TypeB.ownerkey)