Синтаксис T-SQL для SCD типа 2
В настоящее время я пытаюсь завершить заключительную часть запроса, который загружает данные типа SCD 2 в измерение. На основании данных, приведенных ниже, я хотел бы создать вывод, который можно вставить в измерение в дополнение к устаревшим старым записям, истории отслеживания и т. Д. Данные таковы, что у меня есть самые последние записи, в которых атрибуты изменились. Измененные значения находятся в столбцах "Уточняющий запрос" вместе с параметром dateOfchange, то есть датой изменения. Очевидно, этот dateOfchange должен стать датой validTo самой последней записи.
Пример данных выглядит следующим образом:
CREATE TABLE #tstDimPortfolio
(
[ID][INT] IDENTITY (1,1) NOT NULL,
[UPI] [varchar](20) NOT NULL,
[MF_CODE] [varchar](10) NULL,
[BH_Code] [varchar](10) NULL,
[CR_Code] [varchar](10) NULL,
[ValidFrom][varchar](10) NOT NULL,
[ValidTo][varchar](10) NULL,
[IsCurrent] [CHAR] (1) NULL,
[DateofChange] [varchar](10) NULL,
[LookupMF_CODE] [varchar](10) NULL,
[LookupBH_Code] [varchar](10) NULL,
[LookupCR_Code] [varchar](10) NULL,
)
INSERT INTO #tstDimPortfolio
SELECT 'B06531','B06531','','B06531','20111230',NULL,'Y','20120101','','B06531', ''
UNION ALL
SELECT 'BLI003','','BLI003','BBL_WORLD','20111230',NULL,'Y','20120102','BLI004','', ''UNION ALL
SELECT 'BLI003','','BLI003','BBL_WORLD','20111230',NULL,'Y','20120103','BLI005','', ''UNION ALL
SELECT 'BLI027','BLI027','L147','BBL_GBN','20111230',NULL,'Y','20120104','','L146', ''
С этими данными новый вывод должен быть
UPI MF_CODE BH_Code CR_Code ValidFrom ValidTo IsCurrent
_______________________________________________________________________
B06531 B06531 B06531 20111230 20120101 N
B06531 B06531 B06531 B06531 20120101 NULL Y
BLI003 BLI003 BBL_WORLD 20111230 20120102 N
BLI003 BLI004 BLI003 BBL_WORLD 20120102 20120103 N
BLI003 BLI005 BLI003 BBL_WORLD 20120103 NULL Y
BLI027 BLI027 L147 BBL_GBN 20111230 20120104 N
BLI027 BLI027 L146 BBL_GBN 20120104 NULL Y
есть идеи
2 ответа
Мне удалось получить желаемый результат с помощью рекурсивного cte. UPI - это естественный ключ. Однако на самом деле события происходят из отдельного файла, который поворачивается и присоединяется к измерению. (BLI003) было 2 строки, поскольку у него было два события. sql был следующим:
CREATE TABLE #tstDimPortfolio
(
[ID][INT] IDENTITY (1,1) NOT NULL,
[UPI] [varchar](20) NOT NULL,
[MF_CODE] [varchar](10) NULL,
[BH_Code] [varchar](10) NULL,
[CR_Code] [varchar](10) NULL,
[ValidFrom][varchar](10) NOT NULL,
[ValidTo][varchar](10) NULL,
[IsCurrent] [CHAR] (1) NULL,
[DateofChange] [varchar](10) NULL,
[LookupMF_CODE] [varchar](10) NULL,
[LookupBH_Code] [varchar](10) NULL,
[LookupCR_Code] [varchar](10) NULL,
)
INSERT INTO #tstDimPortfolio
SELECT 'B06531','B06531','','B06531','20111230',NULL,'Y','20120101','','B06531', ''UNION ALL
SELECT 'BLI003','','BLI003','BBL_WORLD','20111230',NULL,'Y','20120102','BLI004','', ''UNION ALL
SELECT 'BLI003','','BLI003','BBL_WORLD','20111230',NULL,'Y','20120103','','BLI005', ''UNION ALL
SELECT 'BLI027','BLI027','L147','BBL_GBN','20111230',NULL,'Y','20120104','','L146', ''
SELECT ROW_NUMBER() OVER (PARTITION BY UPI ORDER BY UPI, DateofChange) Sequence,
UPI,
CASE WHEN LookupMF_CODE <> '' THEN LookupMF_CODE ELSE MF_CODE END MF_CODE,
CASE WHEN LookupMF_CODE <> '' THEN LookupBH_Code ELSE BH_Code END BH_Code,
CASE WHEN LookupCR_Code <> '' THEN LookupCR_Code ELSE CR_Code END CR_Code,
ValidFrom, ValidTo, IsCurrent, DateofChange,
LookupMF_CODE,
LookupBH_CODE,
LookupCR_CODE
INTO #Dimension_Table
FROM #tstDimPortfolio
;WITH AddedDim AS
(SELECT * FROM
(
SELECT
ROW_NUMBER() OVER (PARTITION BY UPI ORDER BY UPI, DateofChange) Sequence,
UPI,
CASE WHEN LookupMF_CODE <> '' THEN LookupMF_CODE ELSE MF_CODE END MF_CODE,
CASE WHEN LookupBH_CODE <> '' THEN LookupBH_Code ELSE BH_Code END BH_Code,
CASE WHEN LookupCR_Code <> '' THEN LookupCR_Code ELSE CR_Code END CR_Code,
DateofChange AS ValidFrom,
ValidTo,
IsCurrent
FROM #tstDimPortfolio
)A
WHERE SEQUENCE = 1
UNION ALL
SELECT
DT.Sequence
, DT.UPI
,CASE WHEN DT.LookupMF_CODE <> '' THEN DT.LookupMF_CODE ELSE DM.MF_CODE END MF_CODE
,CASE WHEN DT.LookupBH_CODE <> '' THEN DT.LookupBH_Code ELSE DM.BH_Code END BH_Code
,CASE WHEN DT.LookupCR_Code <> '' THEN DT.LookupCR_Code ELSE DM.CR_Code END CR_Code
,DT.DateofChange AS ValidFrom
,DT.ValidTo
,DT.IsCurrent
FROM #Dimension_Table dt inner join
AddedDim dm
on DT.UPI = DM.UPI
AND dt.Sequence = DM.Sequence + 1
)
SELECT * INTO #temp FROM AddedDim
Я не понимаю, какой твой естественный ключ находится на этом столе. Это "UPI?" Если это так, у вас есть две записи (BLI003) с одним и тем же UPI, но обе они активны, что никогда не должно иметь место.
Во всяком случае, предположим, что это UPI. Если мы хотим обновить B06531, поместите ваши обновления в таблицу:
CREATE TABLE #tstDimPortfolioUpdates
(
[ID][INT] IDENTITY (1,1) NOT NULL,
[UPI] [varchar](20) NOT NULL,
[MF_CODE] [varchar](10) NULL,
[BH_Code] [varchar](10) NULL,
[CR_Code] [varchar](10) NULL,
[ValidFrom][varchar](20) NOT NULL,
[ValidTo][varchar](15) NULL,
[IsCurrent] [CHAR] (1) NULL,
[DateofChange] [varchar](10) NULL,
[LookupMF_CODE] [varchar](10) NULL,
[LookupBH_Code] [varchar](10) NULL,
[LookupCR_Code] [varchar](10) NULL,
)
INSERT INTO #tstDimPortfolioUpdates
SELECT 'B06531','B06531','B06531','B06531','20120102',NULL,'Y','20120102','','B06531', ''
Установите любые записи, которые больше не должны быть активными, изменив значения ValidTo, IsCurrent и DateOfChange
UPDATE dp
SET ValidTo = '20120101', IsCurrent = 'N', DateOfChange = '20120101'
FROM #tstDimPortfolio dp
INNER JOIN #tstDimPortfolioUpdates up ON dp.UPI = up.UPI
AND dp.IsCurrent = 'Y'
Вставьте новые записи
INSERT INTO #tstDimPortfolio (UPI, MF_Code, BH_Code, CR_Code, ValidFrom, ValidTo
,IsCurrent, DateOfChange, LookupMF_Code, LookupBH_Code, LookupCR_Code)
SELECT UPI, MF_Code, BH_Code, CR_Code, ValidFrom, ValidTo
,IsCurrent, DateOfChange, LookupMF_Code, LookupBH_Code, LookupCR_Code
FROM #tstDimPortfolioUpdates
Дважды проверьте правильность обновления
SELECT * FROM #tstDimPortfolio
ORDER BY UPI