Home > Back-end >  Prioritise temporary contract over permanent
Prioritise temporary contract over permanent

Time:08-02

I need to show everyone with their most current contract/s, I've used MAX on the contract start date to achieve this. Where someone has a temporary contract which is newer than their current permanent contract I would only like to show the temporary contract.

     ID     Name   Contract Start    Department        Contract Status
     ab     Dave      2020-06-01      Finance         Permanent Contract
     de     Sam       2022-06-01      Finance         Temporary Contract
     de     Sam       2021-04-13      HR              Permanent Contract
     jd     Jill      2019-03-01      I.T             Permanent Contract
     jd     Jill      2018-04-01      Supplies        Permanent Contract
     jd     Jill      2017-03-01      Admin           Permanent Contract
     pe     Pete      2019-04-01      Finance         Temporary Contract  

What I would like to see

      ID     Name   Contract Start    Department        Contract Status
      ab     Dave      2020-06-01      Finance         Permanent Contract
      de     Sam       2022-06-01      Finance         Temporary Contract
      jd     Jill      2019-03-01      I.T             Permanent Contract
      jd     Jill      2018-04-01      Supplies        Permanent Contract
      jd     Jill      2017-03-01      Admin           Permanent Contract
      pe     Pete      2019-04-01      Finance         Temporary Contract 

I thought a row number partition would solve my problem

 select
 Row_Number() over (partition by ID ORDER BY ContractStart DESC) as [Row_Number],
 ID,
 Name,
 MAX(Contract_Start),
 Department,
 Contract Status

 from various tables 

 group by Id,name,contract_start,department

 where Row_Number = 1

Row_Number     ID     Name   Contract Start    Department        Contract Status
   1           ab     Dave      2020-06-01      Finance         Permanent Contract
   1           de     Sam       2022-06-01      Finance         Temporary Contract
   1           jd     Jill      2017-03-01      I.T             Permanent Contract
   1           pe     Pete      2019-04-01      Finance         Temporary Contract

This works with Sam's contract but unfortunately this method loses Jill's 2 other permanent contracts.

CodePudding user response:

You can use not exists with a correlated query:

select * 
from t
where not exists (
  select * from t t2 
  where t2.id = t.id 
    and t.Contract_Status = 'Permanent Contract' 
    and t2.Contract_Status = 'Temporary Contract' 
    and t2.Contract_Start > t.Contract_Start
);

CodePudding user response:

I would break it into the union of two queries. First, get all the temporary contracts. Then union that with the permanent contracts excluding anyone with a temporary contract.

Example:

WITH temps AS (
select 
 ID,
 Name,
 MAX(Contract_Start),
 Department,
 Contract Status
from various_tables 
where [Contract Status] = 'Temporary Contract'
group by ID,Name,Department,[Contract Status]
),

perms AS (
select 
 ID,
 Name,
 MAX(Contract_Start),
 Department,
 Contract Status
from various_tables 
where [Contract Status] = 'Permanent Contract'
group by ID,Name,Department,[Contract Status]
)

SELECT * 
FROM temps

UNION

SELECT * 
FROM perms 
WHERE ID NOT IN (SELECT ID FROM temps)
  • Related