更新DimEmployee表中的EndDate

huangapple go评论93阅读模式
英文:

Updating EndDate in DimEmployee table

问题

以下是您提供的内容的中文翻译:

我一直在编写一个脚本来创建一个Type2 DimEmployee表。我希望每当员工的详细信息发生更改时,它都会创建一个新的记录。

我相信我已经正确地完成了这部分工作。我卡住的地方是如何正确更新已更改记录的EndDate。

对于没有更改的记录,它的EndDate是NULL。
对于一个月是这样,下个月是那样的记录,它也能插入正确的EndDate值。

然而,当Staging_Employees中有多个相同的记录,然后发生更改时,它就不使用正确的EndDate值。

附注:分期表中的日期字段充当快照日期

有谁可以帮助我吗?

谢谢

例如:

更新DimEmployee表中的EndDate

更新DimEmployee表中的EndDate

更新DimEmployee表中的EndDate

如您所见,DimEmployee表中第一条记录的EndDate现在是2023年2月28日,这是StaffNo 4078之前出现不同记录的最后相同记录的日期。对于第二条记录,EndDate保持为NULL,因为它之后没有StaffNo 4078的记录。

使用的代码:

(此处省略了代码部分,如果需要继续翻译,请提供特定的代码段或问题。)

英文:

I have been working on a script to create a Type2 DimEmployee Table. I want it to create a new record every time there is a change to the employees details.

I believe I have this part working correctly. What I am stuck on is correctly updating the EndDate for records that have changed.

It works were records have not changed the EndDate is NULL
it also works for records were one month it was this and then the next month it was that (it inserts the correct EndDate value).

However where it is not working is when there has been multiple identical records in the Staging_Employees and then there has been a change. It does not use the correct EndDate value.

P.S the Date feild in the staging table acts as a snapshot date

can anyone help me with this?

Thanks

For example:

更新DimEmployee表中的EndDate

更新DimEmployee表中的EndDate

更新DimEmployee表中的EndDate

As you can see, the EndDate for the first record in the DimEmployee table is now 28/02/2023, the date of the last identical record before a different record appears for StaffNo 4078. For the second record, EndDate remains NULL as there are no more records for StaffNo 4078 after it.

Code Used:

  1. BEGIN TRY
  2. TRUNCATE TABLE DimEmployee;
  3. END TRY
  4. BEGIN CATCH
  5. CREATE TABLE DimEmployee (
  6. DimEmployeeID INT IDENTITY(1,1) PRIMARY KEY,
  7. StructureID INT,
  8. StaffNo INT NOT NULL,
  9. EmployeeID INT,
  10. Position varchar(20),
  11. JobTitle VARCHAR(100),
  12. ContractType VARCHAR(50),
  13. AverageHoursPerWeek DECIMAL(5,2),
  14. WeeksPeryr DECIMAL(5,2),
  15. HoursPerWeek DECIMAL(5,2),
  16. PublicHolidayZone VARCHAR(50),
  17. FTE DECIMAL(5,2),
  18. AnalysisGroup VARCHAR(50),
  19. EffectiveDate DATE,
  20. EndDate DATE
  21. );
  22. END CATCH;
  23. -- Insert new records with changes in the specified fields
  24. WITH ChangedRecords AS (
  25. SELECT
  26. s.StaffNo,
  27. RANK() OVER (ORDER BY s.StaffNo) AS EmployeeID,
  28. s.Position,
  29. s.JobTitle,
  30. s.ContractType,
  31. s.AverageHoursPerWeek,
  32. s.WeeksPeryr,
  33. s.HoursPerWeek,
  34. s.PublicHolidayZone,
  35. s.FTE,
  36. s.AnalysisGroup,
  37. d.StructureID,
  38. s.Date,
  39. LAG(d.StructureID) OVER (PARTITION BY s.StaffNo ORDER BY s.Date) AS PreviousStructureID,
  40. LAG(s.Position) OVER (PARTITION BY s.StaffNo ORDER BY s.Date) AS PreviousPosition,
  41. LAG(s.JobTitle) OVER (PARTITION BY s.StaffNo ORDER BY s.Date) AS PreviousJobTitle,
  42. LAG(s.ContractType) OVER (PARTITION BY s.StaffNo ORDER BY s.Date) AS PreviousContractType,
  43. LAG(s.AverageHoursPerWeek) OVER (PARTITION BY s.StaffNo ORDER BY s.Date) AS PreviousAverageHoursPerWeek,
  44. LAG(s.WeeksPeryr) OVER (PARTITION BY s.StaffNo ORDER BY s.Date) AS PreviousWeeksPeryr,
  45. LAG(s.HoursPerWeek) OVER (PARTITION BY s.StaffNo ORDER BY s.Date) AS PreviousHoursPerWeek,
  46. LAG(s.PublicHolidayZone) OVER (PARTITION BY s.StaffNo ORDER BY s.Date) AS PreviousPublicHolidayZone,
  47. LAG(s.FTE) OVER (PARTITION BY s.StaffNo ORDER BY s.Date) AS PreviousFTE,
  48. LAG(s.AnalysisGroup) OVER (PARTITION BY s.StaffNo ORDER BY s.Date) AS PreviousAnalysisGroup,
  49. ROW_NUMBER() OVER (PARTITION BY s.StaffNo, YEAR(s.Date), MONTH(s.Date), DAY(s.Date) ORDER BY s.Date) AS RowNum
  50. FROM Staging_Employees AS s
  51. JOIN DimStructure AS d ON
  52. s.Directorate = d.Directorate AND
  53. s.Service = d.Service AND
  54. s.Section = d.Section AND
  55. s.Team = d.Team
  56. )
  57. INSERT INTO DimEmployee (StructureID, StaffNo, EmployeeID, Position, JobTitle, ContractType, AverageHoursPerWeek, WeeksPeryr, HoursPerWeek, PublicHolidayZone, FTE, AnalysisGroup, EffectiveDate, EndDate)
  58. SELECT StructureID, StaffNo, EmployeeID, Position, JobTitle, ContractType, AverageHoursPerWeek, WeeksPeryr, HoursPerWeek, PublicHolidayZone, FTE, AnalysisGroup, Date, NULL
  59. FROM ChangedRecords
  60. WHERE (PreviousStructureID IS NULL OR PreviousStructureID <> StructureID
  61. OR PreviousPosition <> Position
  62. OR PreviousJobTitle <> JobTitle
  63. OR PreviousContractType <> ContractType
  64. OR PreviousAverageHoursPerWeek <> AverageHoursPerWeek
  65. OR PreviousWeeksPeryr <> WeeksPeryr
  66. OR PreviousHoursPerWeek <> HoursPerWeek
  67. OR PreviousPublicHolidayZone <> PublicHolidayZone
  68. OR PreviousFTE <> FTE
  69. OR PreviousAnalysisGroup <> AnalysisGroup);
  70. -- Update EndDate for old records with changes in the specified fields
  71. WITH ChangedRecords AS (
  72. SELECT
  73. s.StaffNo,
  74. RANK() OVER (ORDER BY s.StaffNo) AS EmployeeID,
  75. s.Position,
  76. s.JobTitle,
  77. s.ContractType,
  78. s.AverageHoursPerWeek,
  79. s.WeeksPeryr,
  80. s.HoursPerWeek,
  81. s.PublicHolidayZone,
  82. s.FTE,
  83. s.AnalysisGroup,
  84. d.StructureID,
  85. s.Date,
  86. LAG(d.StructureID) OVER (PARTITION BY s.StaffNo ORDER BY s.Date) AS PreviousStructureID,
  87. LAG(s.Position) OVER (PARTITION BY s.StaffNo ORDER BY s.Date) AS PreviousPosition,
  88. LAG(s.JobTitle) OVER (PARTITION BY s.StaffNo ORDER BY s.Date) AS PreviousJobTitle,
  89. LAG(s.ContractType) OVER (PARTITION BY s.StaffNo ORDER BY s.Date) AS PreviousContractType,
  90. LAG(s.AverageHoursPerWeek) OVER (PARTITION BY s.StaffNo ORDER BY s.Date) AS PreviousAverageHoursPerWeek,
  91. LAG(s.WeeksPeryr) OVER (PARTITION BY s.StaffNo ORDER BY s.Date) AS PreviousWeeksPeryr,
  92. LAG(s.HoursPerWeek) OVER (PARTITION BY s.StaffNo ORDER BY s.Date) AS PreviousHoursPerWeek,
  93. LAG(s.PublicHolidayZone) OVER (PARTITION BY s.StaffNo ORDER BY s.Date) AS PreviousPublicHolidayZone,
  94. LAG(s.FTE) OVER (PARTITION BY s.StaffNo ORDER BY s.Date) AS PreviousFTE,
  95. LAG(s.AnalysisGroup) OVER (PARTITION BY s.StaffNo ORDER BY s.Date) AS PreviousAnalysisGroup
  96. FROM Staging_Employees AS s
  97. JOIN DimStructure AS d ON
  98. s.Directorate = d.Directorate AND
  99. s.Service = d.Service AND
  100. s.Section = d.Section AND
  101. s.Team = d.Team
  102. )
  103. UPDATE de
  104. SET EndDate = (
  105. SELECT MAX(se.Date)
  106. FROM Staging_Employees se
  107. WHERE de.StaffNo = se.StaffNo
  108. AND se.Date <= de.EffectiveDate
  109. )
  110. FROM DimEmployee de
  111. WHERE de.EndDate IS NULL
  112. AND EXISTS (
  113. SELECT 1
  114. FROM ChangedRecords cr
  115. WHERE cr.StaffNo = de.StaffNo
  116. AND cr.EmployeeID = de.EmployeeID
  117. AND cr.Date > de.EffectiveDate
  118. AND (
  119. cr.PreviousStructureID <> cr.StructureID
  120. OR cr.PreviousPosition <> cr.Position
  121. OR cr.PreviousJobTitle <> cr.JobTitle
  122. OR cr.PreviousContractType <> cr.ContractType
  123. OR cr.PreviousAverageHoursPerWeek <> cr.AverageHoursPerWeek
  124. OR cr.PreviousWeeksPeryr <> cr.WeeksPeryr
  125. OR cr.PreviousHoursPerWeek <> cr.HoursPerWeek
  126. OR cr.PreviousPublicHolidayZone <> cr.PublicHolidayZone
  127. OR cr.PreviousFTE <> cr.FTE
  128. OR cr.PreviousAnalysisGroup <> cr.AnalysisGroup
  129. )
  130. );

答案1

得分: 0

根据您提供的内容,涉及更新多次更改的记录的EndDate的问题可能与您用于获取新EndDate的子查询有关,因为它似乎只考虑了小于或等于记录被更新的EffectiveDate的Staging_Employees表中的最大日期。

这个子查询可能没有考虑到在这个范围内可能发生的多次更改。

要解决此问题,您需要修改子查询,以考虑小于或等于EffectiveDate并且大于先前EndDate的记录的最大日期。这将确保您选择了具有多次更改的记录的正确EndDate。

  1. -- 更新具有指定字段更改的旧记录的EndDate
  2. WITH ChangedRecords AS (
  3. -- 与之前相同
  4. )
  5. UPDATE de
  6. SET EndDate = (
  7. SELECT MAX(se.Date)
  8. FROM Staging_Employees se
  9. WHERE de.StaffNo = se.StaffNo
  10. AND se.Date <= de.EffectiveDate
  11. AND se.Date > COALESCE(de.EndDate, '1900-01-01') -- 考虑在先前EndDate之后的日期
  12. )
  13. FROM DimEmployee de
  14. WHERE de.EndDate IS NULL
  15. AND EXISTS (
  16. SELECT 1
  17. FROM ChangedRecords cr
  18. WHERE cr.StaffNo = de.StaffNo
  19. AND cr.EmployeeID = de.EmployeeID
  20. AND cr.Date > de.EffectiveDate
  21. AND (
  22. cr.PreviousStructureID <> cr.StructureID
  23. OR cr.PreviousPosition <> cr.Position
  24. OR cr.PreviousJobTitle <> cr.JobTitle
  25. OR cr.PreviousContractType <> cr.ContractType
  26. OR cr.PreviousAverageHoursPerWeek <> cr.AverageHoursPerWeek
  27. OR cr.PreviousWeeksPeryr <> cr.WeeksPeryr
  28. OR cr.PreviousHoursPerWeek <> cr.HoursPerWeek
  29. OR cr.PreviousPublicHolidayZone <> cr.PublicHolidayZone
  30. OR cr.PreviousFTE <> cr.FTE
  31. OR cr.PreviousAnalysisGroup <> cr.AnalysisGroup
  32. )
  33. );

希望这可以帮助您解决问题。

英文:

Based on what you provided, the issue with updating the EndDate for records that have changed multiple times may be related to the subquery you are using to get the new EndDate since it seems that it only considers the maximum date from the Staging_Employees table that is less than or equal to the EffectiveDate of the record being updated.

This subquery may not take into account the multiple changes that might have occurred within that range.

To resolve this issue, you need to modify the subquery to consider the maximum date that is both less than or equal to the EffectiveDate and also greater than the previous EndDate of the record being updated. This will ensure that you're selecting the correct EndDate for records that have multiple changes.

  1. -- Update EndDate for old records with changes in the specified fields
  2. WITH ChangedRecords AS (
  3. -- Same as before
  4. )
  5. UPDATE de
  6. SET EndDate = (
  7. SELECT MAX(se.Date)
  8. FROM Staging_Employees se
  9. WHERE de.StaffNo = se.StaffNo
  10. AND se.Date &lt;= de.EffectiveDate
  11. AND se.Date &gt; COALESCE(de.EndDate, &#39;1900-01-01&#39;) -- Consider dates after the previous EndDate
  12. )
  13. FROM DimEmployee de
  14. WHERE de.EndDate IS NULL
  15. AND EXISTS (
  16. SELECT 1
  17. FROM ChangedRecords cr
  18. WHERE cr.StaffNo = de.StaffNo
  19. AND cr.EmployeeID = de.EmployeeID
  20. AND cr.Date &gt; de.EffectiveDate
  21. AND (
  22. cr.PreviousStructureID &lt;&gt; cr.StructureID
  23. OR cr.PreviousPosition &lt;&gt; cr.Position
  24. OR cr.PreviousJobTitle &lt;&gt; cr.JobTitle
  25. OR cr.PreviousContractType &lt;&gt; cr.ContractType
  26. OR cr.PreviousAverageHoursPerWeek &lt;&gt; cr.AverageHoursPerWeek
  27. OR cr.PreviousWeeksPeryr &lt;&gt; cr.WeeksPeryr
  28. OR cr.PreviousHoursPerWeek &lt;&gt; cr.HoursPerWeek
  29. OR cr.PreviousPublicHolidayZone &lt;&gt; cr.PublicHolidayZone
  30. OR cr.PreviousFTE &lt;&gt; cr.FTE
  31. OR cr.PreviousAnalysisGroup &lt;&gt; cr.AnalysisGroup
  32. )
  33. );

huangapple
  • 本文由 发表于 2023年5月14日 20:35:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76247514.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定