;WITH MonthNames AS ( SELECT MonthNumber = 1, MonthName = N'January' UNION ALL SELECT 2, N'February' UNION ALL SELECT 3, N'March' UNION ALL SELECT 4, N'April' UNION ALL SELECT 5, N'May' UNION ALL SELECT 6, N'June' UNION ALL SELECT 7, N'July' UNION ALL SELECT 8, N'August' UNION ALL SELECT 9, N'September' UNION ALL SELECT 10, N'October' UNION ALL SELECT 11, N'November' UNION ALL SELECT 12, N'December' ), LatestAgeEvidence AS ( SELECT evidence.CharacterID, runRows.ProjectID, EvidenceText = CONCAT(evidence.Value, N' ', evidence.Evidence), AgeValue = TRY_CONVERT(int, CASE WHEN evidence.Value IS NULL THEN NULL WHEN PATINDEX(N'%[^0-9]%', evidence.Value + N'x') = 1 THEN NULL ELSE LEFT(evidence.Value, PATINDEX(N'%[^0-9]%', evidence.Value + N'x') - 1) END), rn = ROW_NUMBER() OVER ( PARTITION BY evidence.CharacterID ORDER BY runRows.CompletedUtc DESC, evidence.CharacterEnrichmentEvidenceID DESC ) FROM dbo.CharacterEnrichmentEvidence evidence INNER JOIN dbo.CharacterEnrichmentRuns runRows ON runRows.CharacterEnrichmentRunID = evidence.CharacterEnrichmentRunID WHERE runRows.Status = N'Completed' AND evidence.FieldName = N'AgeAtStartOfSeries' ), MatchedMonth AS ( SELECT ageEvidence.CharacterID, ageEvidence.ProjectID, ageEvidence.AgeValue, monthNames.MonthNumber, MonthPosition = CHARINDEX(monthNames.MonthName, ageEvidence.EvidenceText), ageEvidence.EvidenceText FROM LatestAgeEvidence ageEvidence INNER JOIN MonthNames monthNames ON CHARINDEX(monthNames.MonthName, ageEvidence.EvidenceText) > 0 WHERE ageEvidence.rn = 1 AND ageEvidence.AgeValue BETWEEN 1 AND 120 ), Parts AS ( SELECT matched.CharacterID, matched.ProjectID, matched.AgeValue, matched.MonthNumber, DayValue = TRY_CONVERT(int, REPLACE(REPLACE(REPLACE(REPLACE(dayParts.DayToken, N'st', N''), N'nd', N''), N'rd', N''), N'th', N'')), YearValue = TRY_CONVERT(int, LEFT(LTRIM(SUBSTRING(matched.EvidenceText, matched.MonthPosition + LEN(monthNames.MonthName), 20)), 4)) FROM MatchedMonth matched INNER JOIN MonthNames monthNames ON monthNames.MonthNumber = matched.MonthNumber CROSS APPLY ( SELECT Prefix = RTRIM(CASE WHEN matched.MonthPosition > 1 THEN LEFT(matched.EvidenceText, matched.MonthPosition - 1) ELSE N'' END) ) prefixParts CROSS APPLY ( SELECT LastSpaceFromEnd = CHARINDEX(N' ', REVERSE(prefixParts.Prefix)) ) spaceParts CROSS APPLY ( SELECT DayToken = CASE WHEN LEN(prefixParts.Prefix) = 0 THEN N'' WHEN spaceParts.LastSpaceFromEnd = 0 THEN prefixParts.Prefix ELSE RIGHT(prefixParts.Prefix, spaceParts.LastSpaceFromEnd - 1) END ) dayParts ), Derived AS ( SELECT CharacterID, ProjectID, DateOfBirth = DATEADD(year, -AgeValue, DATEFROMPARTS(YearValue, MonthNumber, DayValue)) FROM Parts WHERE DayValue BETWEEN 1 AND 31 AND YearValue BETWEEN 1000 AND 9999 ) UPDATE c SET BirthDate = derived.DateOfBirth, UpdatedDate = SYSUTCDATETIME() FROM dbo.Characters c INNER JOIN Derived derived ON derived.CharacterID = c.CharacterID AND derived.ProjectID = c.ProjectID WHERE c.BirthDate IS NULL; GO