I need to find possible couplings of employees and department that they worked for. I need to include only the couplings of 2 different departments, so if an employee worked for more than 2 departments, I need to divide them into couplings of 2 departments to show the transfers. Also the period of the contract of the employee at the first department must be earlier than the contract at the second department. I need to list the values as “first_name”, “last_name, “deptnr1”, “dept1”, “deptnr2”, “dept2”.
For example John Doe worked for department A(deptnr 9) from 01/01/2016 to 06/06/2016 and for department B(deptnr 3) from 10/06/2016 to 12/12/2017, the result should be like :
John, Doe, 9, A, 3, B
If he then returned to his job at department A, there should be another coupling like this to make his 2nd transfer visible:
John, Doe, 3, B, 9, A
so if he transfers around, we should have as many couplings of departments as possible, in this case 2 transfers, thus 2 couplings out of 3 departments(A => B => A so A,B/B,A).
I have 4 tables.
Person (PK email, first_name, last_name, FK postcode, FK place_name) Employee(PK employeenr, FK email) Department(PK departmentnr, name, FK postcode, FK place_name) Contract(PK periode_begin, PK periode_end, FK departmentnr, FK employeenr)
I have tried this but I don’t know how to make use of aliases to take values from let’s say department.name and put them on other columns as name1 and name2. Also I couldn’t figure out a way to make couplings out of let’s say four transfers like (A=> B=> C=> D=> E TO A,B/B,C/C,D/D,E).
SELECT
first_name,
last_name,
d1.departmentnr AS deptnr1,
d1.name AS dept1,
d2.departmentnr AS deptnr2,
d2.name AS dept2,
FROM person
INNER JOIN employee ON employee.email=person.email
INNER JOIN contract ON contract.employeenr = employee.employeenr
INNER JOIN department d1 ON department.departmentnr = contract.departmentnr
where contract.employeenr in
(SELECT employeenr FROM contract
GROUP BY employeenr HAVING COUNT(employeenr)>1
AND COUNT(employeenr)>1)
Advertisement
Answer
Use the window function lead()
select
first_name,
last_name,
deptnr1,
dept1,
deptnr2,
dept2
from (
select
first_name,
last_name,
departmentnr as deptnr1,
name as dept1,
lead(departmentnr) over w as deptnr2,
lead(name) over w as dept2,
periode_begin
from person p
join employee e using(email)
join contract c using(employeenr)
join department d using(departmentnr)
window w as (partition by email order by periode_begin)
) s
where deptnr2 is not null
order by first_name, last_name, periode_begin
Read also about window functions in the documentation.