I have an HR table H with information about employees and a period table with dates and all periods(months). I may have a situation when one person. I'm joining them because I need to have information about every month(for other tasks). But I may have situation when one person(A) leaves in the middle of the month, B person starts his position in the middle of the same month. In this case for the current month I have to consider that person A is working on this position. Could you please help me to do it? Thank you very much in advance!
SELECT
,H.[PERSON_ID]
,H.[TITLE]
,H.[START_DATE]
,H.[END_DATE]
,IsNUll(H.END_DATE, Cast(getdate() as date)) as ED
,H.[DESCRIPTION]
,Per.PeriodID
,Per.CalDateStart
,Per.CalDateEnd
FROM H
inner join Period Per
on IsNUll(H.END_DATE, Cast(getdate() as date)) >= Per.CalDateStart
and H.START_DATE <= Cast(Per.CalDateEnd as date)
Where 1 = 1
and PERSON_ID in (73, 81)
To solve the problem:
Per.CalDateStart
of one period, safely consider the employee was working during that period.on IsNUll(H.END_DATE, Cast(getdate() as date)) >= Per.CalDateStart
and H.START_DATE <= Per.CalDateStart
To further optimize:
Use RIGHT JOIN to retain every single period in your Per table, making sure that we "have information about every month for the other tasks".
Use ORDER BY to sort the periods, for two benefits:
SELECT
,H.[PERSON_ID]
-- unchanged snippet --
FROM H
right join Period Per
on IsNUll(H.END_DATE, Cast(getdate() as date)) >= Per.CalDateStart
and H.START_DATE <= Per.CalDateStart
Where 1 = 1
and PERSON_ID in (73, 81)
ORDER BY Per.CalDateStart
-- Content below was appended on 2022-08-24 --
To aggregate, making one period binded with at most one empolyee:
Per.PeriodID
) into just one row. This one row shall be the row that has, saying, the earliest H.[START_DATE]
.
SELECT
,H.[PERSON_ID]
,H.[TITLE]
,MIN(H.[START_DATE]) -- aggregation condition
-- unchanged snippet --
and PERSON_ID in (73, 81)
GROUP BY Per.PeriodID -- aggregation
ORDER BY Per.CalDateStart
(Optional) To exclude the rows that have no empolyee binded:
-- unchanged snippet --
GROUP BY Per.PeriodID
HAVING COUNT(H.[PERSON_ID]) > 0
ORDER BY Per.CalDateStart
-- Content below was appended on 2022-08-25 --
To summarize:
SELECT
,H.[PERSON_ID]
,H.[TITLE]
,MIN(H.[START_DATE])
,H.[END_DATE]
,IsNUll(H.END_DATE, Cast(getdate() as date)) as ED
,H.[DESCRIPTION]
,Per.PeriodID
,Per.CalDateStart
,Per.CalDateEnd
FROM H
right join Period Per
on IsNUll(H.END_DATE, Cast(getdate() as date)) >= Per.CalDateStart
and H.START_DATE <= Per.CalDateStart
Where 1 = 1
and PERSON_ID in (73, 81)
GROUP BY Per.PeriodID
HAVING COUNT(H.[PERSON_ID]) > 0
ORDER BY Per.CalDateStart