Comparez deux colonnes les plus récentes pour le même ID

J'ai une table pour les adresses des personnes. La colonne Class indique s'il s'agit d'une adresse de domicile ( H ), postale ( P ) ou interne ( I ). Chaque fois qu'une personne met à jour l'adresse, la date est également enregistrée.

L'adresse interne est utilisée par mon entreprise lorsqu'une correspondance nous est renvoyée en raison d'adresses incorrectes, nous la mettons donc à jour à notre adresse jusqu'à ce que nous puissions get de nouvelles coordonnées.

J'aimerais savoir quelles personnes ont changé d'adresse postale ou de domicile avec une date d'input en vigueur après la date d'input en vigueur de l'adresse interne.

Voici un exemple de ce à quoi ressemble la table:

 | **PersonID**| **Class** | **EffDate** | **Line1** | 1 | H | 12/01/2010 | 31 Academy Avenue | 1 | H | 13/09/2010 | 433 Hillcrest Drive | 1 | I | 26/10/2015 | 1 Bond Circle | 2 | H | 17/12/2012 | 761 Circle St. | 2 | H | 12/11/2013 | 597 Elm Lane | 2 | I | 1/10/2015 | 1 Bond Circle | 2 | H | 6/12/2016 | 8332 Mountainview St. | 3 | P | 27/09/2010 | 8 Bow Ridge Lane | 3 | H | 6/12/2010 | 22 Shady St. | 3 | I | 7/12/2015 | 1 Bond Circle | 3 | H | 8/12/2016 | 7423 Rockcrest Ave. | 4 | P | 9/12/2015 | 888 N. Shady Street | 4 | I | 10/12/2016 | 1 Bond Circle 

J'aimerais que la requête ne renvoie que:

 | **PersonID**| **Class** | **EffDate** | **Line1** | 2 | H | 6/12/2016 | 8332 Mountainview St. | 3 | H | 8/12/2016 | 7423 Rockcrest Ave. 

Des idées? J'utilise SQL Server 2012.

Voici une méthode:

 select t.* from t where t.class in ('H', 'P') and t.effdate > (select max(t2.effdate) from t t2 where t2.class = 'I' and t2.personId = t.personId ); 

Une autre méthode qui utilise des fonctions de window:

 select t.* from (select t.*, max(case when class = 'I' then date end) over (partition by personid) as max_idate from t ) t where t.class in ('H', 'P') and t.date > t.maxidate;