I don't think you want dense_rank()
at all. Instead, partition on each contract by whether or not salary is 0. Then use row_number()
to enumerate the values and logic to choose which ones you want:
from (SELECT contract_nbr, business_unit, ymdeff, ymdend, ymdtrans, void, salary,
row_number() over (partition by contract_nbr,
(case when salary = 0 then '0' else '+' end)
order by ymdend desc
) as SalarySeqNum
. . .
) t
where (salary = 0 and salarySeqNum = 1) or
(salary > 0 and salarySeqNum = 2)