用于向前填充行值直到SQL Server中的下一个非空行的SQL代码

n9vozmp4  于 2022-12-22  发布在  SQL Server
关注(0)|答案(2)|浏览(123)

下表中,[MonthEndDate]有非空值。与此相关,从[employeeId]列到[jobDescription]列,所有空值应向前填充第4行到第16行的数据,最后2列即[StaffTypeID][Description]。所有的空值都应该用行1到行12中的数据向前填充,并且对于其余的行类似。
请使用此包含所需CREATE和INSERT语句的db-fiddle链接在问题语句中生成表。
Table 1是问题陈述中的表格,Table 2是所需的输出。
我将不胜感激,如果你能分享所需的SQL代码。

    • 一米七三**

| 月结束日期|雇员ID|最后一天工作生效日期|员工类型|员工状态|计划工时|主管ID|作业代码|作业描述|人员类型ID|说明|
| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------|
| 2013年5月31日|||||||||1个|会计助理|
| 2013年6月30日|||||||||||
| 2013年7月31日|一○一|2013年6月30日|内部|A类|80.0分||C101|实习生-咨询|||
| 2013年8月31日|一○一|2013年8月31日|内部|T型|80.0分||C101|实习生-咨询|||
| 2013年9月30日|||||||||||
| 2013年10月31日|||||||||||
| 2013年11月30日|||||||||||
| 二〇一三年十二月三十一日|||||||||||
| 2014年1月31日|||||||||||
| 2014年2月28日|||||||||||
| 2014年3月31日|||||||||||
| 2014年4月30日|||||||||||
| 2014年5月31日|||||||||五个|顾问|
| 2014年6月30日|||||||||||
| 2014年7月31日|||||||||||
| 2014年8月31日|||||||||||
| 2014年9月30日|一○一|2014年9月30日|注册|A类|80.0分|S101| C201|工作人员顾问|||
| 2014年10月31日|||||||||||
| 2014年11月30日|||||||||||
| 2014年12月31日|||||||||||
| 2015年1月31日|||||||||||
| 2015年2月28日|||||||||||
| 2015年3月31日|||||||||||
| 2015年4月30日|||||||||||
| 2015年5月31日|||||||||||
表二:
| 月结束日期|雇员ID|最后一天工作生效日期|员工类型|员工状态|计划工时|主管ID|作业代码|作业描述|人员类型ID|说明|
| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------|
| 2013年5月31日|||||||||1个|会计助理|
| 2013年6月30日|||||||||1个|会计助理|
| 2013年7月31日|一○一|2013年6月30日|内部|A类|80.0分||C101|实习生-咨询|1个|会计助理|
| 2013年8月31日|一○一|2013年8月31日|内部|T型|80.0分||C101|实习生-咨询|1个|会计助理|
| 2013年9月30日|一○一|2013年8月31日|内部|T型|80.0分||C101|实习生-咨询|1个|会计助理|
| 2013年10月31日|一○一|2013年8月31日|内部|T型|80.0分||C101|实习生-咨询|1个|会计助理|
| 2013年11月30日|一○一|2013年8月31日|内部|T型|80.0分||C101|实习生-咨询|1个|会计助理|
| 二〇一三年十二月三十一日|一○一|2013年8月31日|内部|T型|80.0分||C101|实习生-咨询|1个|会计助理|
| 2014年1月31日|一○一|2013年8月31日|内部|T型|80.0分||C101|实习生-咨询|1个|会计助理|
| 2014年2月28日|一○一|2013年8月31日|内部|T型|80.0分||C101|实习生-咨询|1个|会计助理|
| 2014年3月31日|一○一|2013年8月31日|内部|T型|80.0分||C101|实习生-咨询|1个|会计助理|
| 2014年4月30日|一○一|2013年8月31日|内部|T型|80.0分||C101|实习生-咨询|1个|会计助理|
| 2014年5月31日|一○一|2013年8月31日|内部|T型|80.0分||C101|实习生-咨询|五个|顾问|
| 2014年6月30日|一○一|2013年8月31日|内部|T型|80.0分||C101|实习生-咨询|五个|顾问|
| 2014年7月31日|一○一|2013年8月31日|内部|T型|80.0分||C101|实习生-咨询|五个|顾问|
| 2014年8月31日|一○一|2013年8月31日|内部|T型|80.0分||C101|实习生-咨询|五个|顾问|
| 2014年9月30日|一○一|2014年9月30日|注册|A类|80.0分|S101| C201|工作人员顾问|五个|顾问|
| 2014年10月31日|一○一|2014年9月30日|注册|A类|80.0分|S101| C201|工作人员顾问|五个|顾问|
| 2014年11月30日|一○一|2014年9月30日|注册|A类|80.0分|S101| C201|工作人员顾问|五个|顾问|
| 2014年12月31日|一○一|2014年9月30日|注册|A类|80.0分|S101| C201|工作人员顾问|五个|顾问|
| 2015年1月31日|一○一|2014年9月30日|注册|A类|80.0分|S101| C201|工作人员顾问|五个|顾问|
| 2015年2月28日|一○一|2014年9月30日|注册|A类|80.0分|S101| C201|工作人员顾问|五个|顾问|
| 2015年3月31日|一○一|2014年9月30日|注册|A类|80.0分|S101| C201|工作人员顾问|五个|顾问|

| 2015年4月30日|一○一|2014年9月30日|注册|A类|80.0分|S101| C201|工作人员顾问|五个|顾问|
| 2015年5月31日|一○一|2014年9月30日|注册|A类|80.0分|S101| C201|工作人员顾问|五个|顾问|

iklwldmw

iklwldmw1#

这只显示了对于列employeeId,last_day_jobeffectiveDate如何执行此操作。
它对每列使用孤岛和间隙算法
剩下的你当然要完成
您需要检查每一列的CASE WHEN,因为它决定了哪些情况应该获得MAX值,哪些情况不应该

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

| 月结束日期|雇员ID|最后一天工作生效日期|员工类型|员工状态|计划工时|主管ID|作业代码|作业描述|人员类型ID|说明|
| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------|
| 2013年5月31日| |* 空 *| | | * 无效 | | | |1个|会计助理|
| 2013年6月30日| |
无效 *| | | * 无效 | | | | 无效 ||
| 2013年7月31日|一○一|2013年6月30日|内部|A类|八十| |C101|实习生-咨询|
无效 ||
| 2013年8月31日|一○一|2013年8月31日|内部|T型|八十| |C101|实习生-咨询|
无效 ||
| 2013年9月30日|一○一|2013年8月31日| | |
无效 | | | | 无效 ||
| 二〇一三年十月三十一日|一○一|2013年8月31日| | |
无效 | | | | 无效 ||
| 二〇一三年十一月三十日|一○一|2013年8月31日| | |
无效 | | | | 无效 ||
| 二〇一三年十二月三十一日|一○一|2013年8月31日| | |
无效 | | | | 无效 ||
| 2014年1月31日|一○一|2013年8月31日| | |
无效 | | | | 无效 ||
| 2014年2月28日|一○一|2013年8月31日| | |
无效 | | | | 无效 ||
| 2014年3月31日|一○一|2013年8月31日| | |
无效 | | | | 无效 ||
| 2014年4月30日|一○一|2013年8月31日| | |
无效 | | | | 无效 ||
| 2014年5月31日|一○一|2013年8月31日| | |
无效 | | ||五个|顾问|
| 2014年6月30日|一○一|2013年8月31日| | |
无效 | | | | 无效 ||
| 2014年7月31日|一○一|2013年8月31日| | |
无效 | | | | 无效 ||
| 2014年8月31日|一○一|2013年8月31日| | |
无效 | | | | 无效 ||
| 2014年9月30日|一○一|2014年9月30日|注册|A类|八十|S101| C201|工作人员顾问|
无效 ||
| 二〇一四年十月三十一日|一○一|2014年9月30日| | |
无效 | | | | 无效 ||
| 2014年11月30日|一○一|2014年9月30日| | |
无效 | | | | 无效 ||
| 二〇一四年十二月三十一日|一○一|2014年9月30日| | |
无效 | | | | 无效 ||
| 2015年1月31日|一○一|2014年9月30日| | |
无效 | | | | 无效 ||
| 2015年2月28日|一○一|2014年9月30日| | |
无效 | | | | 无效 ||
| 2015年3月31日|一○一|2014年9月30日| | |
无效 | | | | 无效 ||
| 2015年4月30日|一○一|2014年9月30日| | |
无效 | | | | 无效 ||
| 2015年5月31日|一○一|2014年9月30日| | |
无效 | | | | 无效 *||
fiddle

iswrvxsc

iswrvxsc2#

我的做法稍有不同,因为我没有使用合并,而且还被迫使用额外的CTE来解决employeeStatus问题。我还将我的数据放入临时表中,因此您必须更改它。类似于以下操作可能会起作用:

;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

相关问题