• My first pass:

    CREATE TABLE #EmergencyPhoneNumber(PersonPhoneId int Primary Key,

    PersonId uniqueidentifier,

    PhoneId int,

    IsPrimaryNumber bit,

    PhoneExtension varchar(10),

    Comments varchar(255))

    INSERT INTO #EmergencyPhoneNumber VALUES(1,'4EE56555-91C6-4755-AC8E-0099D297445A',2771,0,'1111','this is phone1')

    INSERT INTO #EmergencyPhoneNumber VALUES(2,'4EE56555-91C6-4755-AC8E-0099D297445A',2771,1,'','this is phone2')

    INSERT INTO #EmergencyPhoneNumber VALUES(3,'4EE56555-91C6-4755-AC8E-0099D297445A',2772,0,1111,'this is phone3')

    ;

    WITH numbertelns AS (

    SELECT ROW_NUMBER() OVER (PARTITION BY PersonID, PhoneID ORDER BY PersonPhoneId) AS rownum,

    PersonId,

    PhoneId,

    IsPrimaryNumber,

    PhoneExtension,

    Comments

    FROM #EmergencyPhoneNumber

    ), grouptelns AS (

    SELECT PersonId,

    PhoneId,

    MAX(PhoneExtension) AS PhoneExtension,

    MAX(CAST (IsPrimaryNumber AS TINYINT)) AS IsPrimaryNumber

    FROM #EmergencyPhoneNumber

    GROUP BY PersonId,PhoneId

    ), keeprow AS (

    SELECT p1.rownum,p1.PersonId,p1.PhoneId,CAST(p2.IsPrimaryNumber AS bit) AS IsPrimaryNumber,p2.PhoneExtension,p1.Comments

    FROM numbertelns p1

    JOIN grouptelns p2

    ON p1.PersonId = p2.PersonId

    AND p1.PhoneId = p2.PhoneId

    WHERE p1.rownum = 1)

    MERGE numbertelns n1

    USING keeprow n2

    ON n1.PersonId = n2.PersonId

    AND n1.PhoneId = n2.PhoneId

    AND n1.rownum = n2.rownum

    WHEN MATCHED THEN

    UPDATE SET n1.PhoneExtension = n2.PhoneExtension,

    n1.IsPrimaryNumber = n2.IsPrimaryNumber

    WHEN NOT MATCHED BY SOURCE THEN DELETE

    ;

    SELECT * FROM #EmergencyPhoneNumber

    DROP TABLE #EmergencyPhoneNumber

    The extension logic may be undesired. You didn't say what to do if the duplicates both had extensions and they did not match. In that case I take the highest one.

    A merge actually does make some sense here, as you need to both update and delete.