In the below table, the [MonthEndDate]
has non-null values. Relative to this, from column [employeeId]
till column [jobDescription]
all null values should be forward-filled with data in the row 4 till row 16 and for last 2 columns i.e. [StaffTypeID]
and [Description]
, all null values should be forward-filled with data in the row 1 till row 12 and similarly for the remaining rows.
Please use this db-fiddle link containing the required CREATE and INSERT statements to generate the table in problem statement.
Table 1
is table in Problem Statement and Table 2
is the desired output.
I would be appreciate if you could share the required SQL code.
Table 1
MonthEndDate | employeeId | last_day_jobeffectiveDate | employeeType | employeeStatus | scheduledWorkHours | supervisorId | jobCode | jobDescription | StaffTypeID | Description |
---|---|---|---|---|---|---|---|---|---|---|
05/31/2013 | 1 | Accounting Assistant | ||||||||
06/30/2013 | ||||||||||
07/31/2013 | E101 | 06/30/2013 | INT | A | 80.0 | C101 | Intern - Consulting | |||
08/31/2013 | E101 | 08/31/2013 | INT | T | 80.0 | C101 | Intern - Consulting | |||
09/30/2013 | ||||||||||
10/31/2013 | ||||||||||
11/30/2013 | ||||||||||
12/31/2013 | ||||||||||
01/31/2014 | ||||||||||
02/28/2014 | ||||||||||
03/31/2014 | ||||||||||
04/30/2014 | ||||||||||
05/31/2014 | 5 | Consultant | ||||||||
06/30/2014 | ||||||||||
07/31/2014 | ||||||||||
08/31/2014 | ||||||||||
09/30/2014 | E101 | 09/30/2014 | REG | A | 80.0 | S101 | C201 | Staff Consultant | ||
10/31/2014 | ||||||||||
11/30/2014 | ||||||||||
12/31/2014 | ||||||||||
01/31/2015 | ||||||||||
02/28/2015 | ||||||||||
03/31/2015 | ||||||||||
04/30/2015 | ||||||||||
05/31/2015 |
Table 2:
MonthEndDate | employeeId | last_day_jobeffectiveDate | employeeType | employeeStatus | scheduledWorkHours | supervisorId | jobCode | jobDescription | StaffTypeID | Description |
---|---|---|---|---|---|---|---|---|---|---|
05/31/2013 | 1 | Accounting Assistant | ||||||||
06/30/2013 | 1 | Accounting Assistant | ||||||||
07/31/2013 | E101 | 06/30/2013 | INT | A | 80.0 | C101 | Intern - Consulting | 1 | Accounting Assistant | |
08/31/2013 | E101 | 08/31/2013 | INT | T | 80.0 | C101 | Intern - Consulting | 1 | Accounting Assistant | |
09/30/2013 | E101 | 08/31/2013 | INT | T | 80.0 | C101 | Intern - Consulting | 1 | Accounting Assistant | |
10/31/2013 | E101 | 08/31/2013 | INT | T | 80.0 | C101 | Intern - Consulting | 1 | Accounting Assistant | |
11/30/2013 | E101 | 08/31/2013 | INT | T | 80.0 | C101 | Intern - Consulting | 1 | Accounting Assistant | |
12/31/2013 | E101 | 08/31/2013 | INT | T | 80.0 | C101 | Intern - Consulting | 1 | Accounting Assistant | |
01/31/2014 | E101 | 08/31/2013 | INT | T | 80.0 | C101 | Intern - Consulting | 1 | Accounting Assistant | |
02/28/2014 | E101 | 08/31/2013 | INT | T | 80.0 | C101 | Intern - Consulting | 1 | Accounting Assistant | |
03/31/2014 | E101 | 08/31/2013 | INT | T | 80.0 | C101 | Intern - Consulting | 1 | Accounting Assistant | |
04/30/2014 | E101 | 08/31/2013 | INT | T | 80.0 | C101 | Intern - Consulting | 1 | Accounting Assistant | |
05/31/2014 | E101 | 08/31/2013 | INT | T | 80.0 | C101 | Intern - Consulting | 5 | Consultant | |
06/30/2014 | E101 | 08/31/2013 | INT | T | 80.0 | C101 | Intern - Consulting | 5 | Consultant | |
07/31/2014 | E101 | 08/31/2013 | INT | T | 80.0 | C101 | Intern - Consulting | 5 | Consultant | |
08/31/2014 | E101 | 08/31/2013 | INT | T | 80.0 | C101 | Intern - Consulting | 5 | Consultant | |
09/30/2014 | E101 | 09/30/2014 | REG | A | 80.0 | S101 | C201 | Staff Consultant | 5 | Consultant |
10/31/2014 | E101 | 09/30/2014 | REG | A | 80.0 | S101 | C201 | Staff Consultant | 5 | Consultant |
11/30/2014 | E101 | 09/30/2014 | REG | A | 80.0 | S101 | C201 | Staff Consultant | 5 | Consultant |
12/31/2014 | E101 | 09/30/2014 | REG | A | 80.0 | S101 | C201 | Staff Consultant | 5 | Consultant |
01/31/2015 | E101 | 09/30/2014 | REG | A | 80.0 | S101 | C201 | Staff Consultant | 5 | Consultant |
02/28/2015 | E101 | 09/30/2014 | REG | A | 80.0 | S101 | C201 | Staff Consultant | 5 | Consultant |
03/31/2015 | E101 | 09/30/2014 | REG | A | 80.0 | S101 | C201 | Staff Consultant | 5 | Consultant |
04/30/2015 | E101 | 09/30/2014 | REG | A | 80.0 | S101 | C201 | Staff Consultant | 5 | Consultant |
05/31/2015 | E101 | 09/30/2014 | REG | A | 80.0 | S101 | C201 | Staff Consultant | 5 | Consultant |
CodePudding user response:
This shows only for the columns employeeId,last_day_jobeffectiveDate
how you can do it.
It uses for every column the island and gaps algorithm
You of course have to complete it for the rest
You need to check the CASE WHEN
for every column, as determins which cases should get then MAX
values and which not
MERGE empworkhours AS tgt
USING (SELECT
[MonthEndDate],
CASE WHEN
([employeeId] IS NULL
OR TRIM([employeeId]) = '')
AND MAX([employeeId]) OVER(
ORDER BY MonthEndDate
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) IS NOT NULL
THEN
MAX([employeeId]) OVER(
ORDER BY MonthEndDate
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
ELSE [employeeId] END as [employeeId]
,CASE WHEN
([last_day_jobeffectiveDate] IS NULL
)
AND MAX([last_day_jobeffectiveDate]) OVER(
ORDER BY MonthEndDate
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) IS NOT NULL
THEN
MAX([last_day_jobeffectiveDate]) OVER(
ORDER BY MonthEndDate
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
ELSE [last_day_jobeffectiveDate] END as [last_day_jobeffectiveDate]
FROM [empworkhours]) as src ([MonthEndDate],employeeId,last_day_jobeffectiveDate)
ON (tgt.[MonthEndDate] = src.[MonthEndDate])
WHEN MATCHED AND tgt.last_day_jobeffectiveDate IS NULL
THEN UPDATE SET tgt.[employeeId] = src.[employeeId],
tgt.[last_day_jobeffectiveDate] = src.[last_day_jobeffectiveDate];
Warning: Null value is eliminated by an aggregate or other SET operation.
22 rows affected
SELECT * FROM empworkhours
MonthEndDate | employeeId | last_day_jobeffectiveDate | employeeType | employeeStatus | scheduledWorkHours | supervisorId | jobCode | jobDescription | StaffTypeID | Description |
---|---|---|---|---|---|---|---|---|---|---|
2013-05-31 | null | null | 1 | Accounting Assistant | ||||||
2013-06-30 | null | null | null | |||||||
2013-07-31 | E101 | 2013-06-30 | INT | A | 80 | C101 | Intern - Consulting | null | ||
2013-08-31 | E101 | 2013-08-31 | INT | T | 80 | C101 | Intern - Consulting | null | ||
2013-09-30 | E101 | 2013-08-31 | null | null | ||||||
2013-10-31 | E101 | 2013-08-31 | null | null | ||||||
2013-11-30 | E101 | 2013-08-31 | null | null | ||||||
2013-12-31 | E101 | 2013-08-31 | null | null | ||||||
2014-01-31 | E101 | 2013-08-31 | null | null | ||||||
2014-02-28 | E101 | 2013-08-31 | null | null | ||||||
2014-03-31 | E101 | 2013-08-31 | null | null | ||||||
2014-04-30 | E101 | 2013-08-31 | null | null | ||||||
2014-05-31 | E101 | 2013-08-31 | null | 5 | Consultant | |||||
2014-06-30 | E101 | 2013-08-31 | null | null | ||||||
2014-07-31 | E101 | 2013-08-31 | null | null | ||||||
2014-08-31 | E101 | 2013-08-31 | null | null | ||||||
2014-09-30 | E101 | 2014-09-30 | REG | A | 80 | S101 | C201 | Staff Consultant | null | |
2014-10-31 | E101 | 2014-09-30 | null | null | ||||||
2014-11-30 | E101 | 2014-09-30 | null | null | ||||||
2014-12-31 | E101 | 2014-09-30 | null | null | ||||||
2015-01-31 | E101 | 2014-09-30 | null | null | ||||||
2015-02-28 | E101 | 2014-09-30 | null | null | ||||||
2015-03-31 | E101 | 2014-09-30 | null | null | ||||||
2015-04-30 | E101 | 2014-09-30 | null | null | ||||||
2015-05-31 | E101 | 2014-09-30 | null | null |
CodePudding user response:
I did this just a little differently as I did not use a merge and was also forced to use an additional CTE to fix the employeeStatus issue. I also put my data into a temp table, so you will have to change that in your fiddle. Something like this might work:
;WITH CTE AS
(
SELECT MonthEndDate, MAX(last_day_jobeffectiveDate) OVER(ORDER BY MonthEndDate ROWS BETWEEN UNBOUNDED PRECEDING and CURRENT ROW) last_day_jobeffectiveDate ,
MAX(employeeType) OVER(ORDER BY MonthEndDate ROWS BETWEEN UNBOUNDED PRECEDING and CURRENT ROW) employeeType,
MAX(EmployeeID) OVER(ORDER BY MonthEndDate ROWS BETWEEN UNBOUNDED PRECEDING and CURRENT ROW) EmployeeID,
MAX(scheduledWorkHours) OVER(ORDER BY MonthEndDate ROWS BETWEEN UNBOUNDED PRECEDING and CURRENT ROW) scheduledWorkHours ,
MAX(supervisorId) OVER(ORDER BY MonthEndDate ROWS BETWEEN UNBOUNDED PRECEDING and CURRENT ROW) supervisorId ,
MAX(JobCode) OVER(ORDER BY MonthEndDate ROWS BETWEEN UNBOUNDED PRECEDING and CURRENT ROW) JobCode,
MAX(JobDescription) OVER(ORDER BY MonthEndDate ROWS BETWEEN UNBOUNDED PRECEDING and CURRENT ROW) JobDescription,
MAX(StaffTypeID) OVER(ORDER BY MonthEndDate ROWS BETWEEN UNBOUNDED PRECEDING and CURRENT ROW) StaffTypeID,
MAX(Description) OVER(ORDER BY MonthEndDate ROWS BETWEEN UNBOUNDED PRECEDING and CURRENT ROW) Description
, t1.employeeStatus
FROM #empworkhours t1
),CTE2 AS
(
SELECT MonthEndDate,
EmployeeID,
last_day_jobeffectiveDate,
employeeType,
MAX(employeeStatus) OVER( Partition by last_day_jobeffectiveDate ORDER BY MonthEndDate ROWS BETWEEN UNBOUNDED PRECEDING and CURRENT ROW ) employeeStatus,
scheduledWorkHours,
supervisorId,
JobCode,
JobDescription,
StaffTypeID,
Description
FROM CTE
)
UPdATE #empworkhours
SET employeeId = t2.EmployeeID
, last_day_jobeffectiveDate = t2.last_day_jobeffectiveDate
,employeeType = t2.employeeType
,employeeStatus = t2.employeeStatus
,scheduledWorkHours = t2.scheduledWorkHours
,supervisorId = t2.supervisorId
,jobCode = t2.JobCode
,jobDescription = t2.JobDescription
,StaffTypeID = t2.StaffTypeID
,Description = t2.Description
FROM CTE2 t2
INNER JOIN #empworkhours t1 on t1.MonthEndDate = t2.MonthEndDate