我需要使用基于表2的正确条目更新表1中的外键。正确的外键是最早的日期,但不是在表2中的下一个生效日期之前。如果有多个条目在表2中具有相同的生效日期,然后使用修改日期列作为平局破坏者并选择最近的一个。这是基于表的结构(所有日期都是日期格式):
Table 1
pK1 PeriodStartDate pK2
1 2016-04-01 00:00:00.000
2 2016-07-01 00:00:00.000
Table 2
pK2 EffectiveFrom ModifiedDate
3 2016-03-01 00:00:00.000 2016-04-01 00:00:00.000
4 2016-05-01 00:00:00.000 2016-06-01 00:00:00.000
5 2016-05-01 00:00:00.000 2016-06-02 00:00:00.000
所以在上面的例子中,表1看起来像这样:
pK1 PeriodStartDate pK2
1 2016-04-01 00:00:00.000 3
2 2016-07-01 00:00:00.000 5
这是因为第1行是在3月1日到5月1日之间(从表2开始)。对于第2行,它是在最后一个日期之后,但由于有两个相似的开始日期,我们选择最后修改日期。
我不确定解决方案。我正在尝试这样的事情:
UPDATE table1
SET pK2 = table2.pK2
FROM table2
WHERE PeriodStartDate > (SELECT FIRST(table2.EffectiveFrom) FROM table2)
我只是不确定如何找到一个受另一行限制的条目(然后需要另一列用于分配器)
答案 0 :(得分:1)
首先,您需要在row_number()
上应用Table2
,在PeriodStart
上进行分区,并按ModifiedDate
(desc)排序。请致电MaxModified
; 1始终是最近修改过的记录。
pK2 PeriodStart ModifiedDate MaxModified
3 2016-03-01 00:00:00.000 2016-04-01 00:00:00.000 1
5 2016-05-01 00:00:00.000 2016-06-02 00:00:00.000 1
4 2016-05-01 00:00:00.000 2016-06-01 00:00:00.000 2
然后,仅在MaxModified=1
的位置添加一个新的“id”,这样我们就可以排队一个开始日期,下一行开始日期(我们的结束日期)。这也是使用row_number()
订购的PeriodStart
函数完成的。
pK2 PeriodStart ModifiedDate MaxModified myID
3 2016-03-01 00:00:00.000 2016-04-01 00:00:00.000 1 1
5 2016-05-01 00:00:00.000 2016-06-02 00:00:00.000 1 2
然后我们获取该结果并将其连接到自己偏移一行以获得每个原始行的结束日期值。
pK2 PeriodStart ModifiedDate MaxModified myID PeriodEnd
3 2016-03-01 00:00:00.000 2016-04-01 00:00:00.000 1 1 2016-05-01 00:00:00.000
5 2016-05-01 00:00:00.000 2016-06-02 00:00:00.000 1 2 NULL
一旦我们拥有了这个,就可以简单地加入开始/结束日期以获得pk2
值。
完整的脚本......
DECLARE @Table1 TABLE (pK1 INT, PeriodStart DATETIME, pK2 INT)
DECLARE @Table2 TABLE (pK2 INT, PeriodStart DATETIME, ModifiedDate DATETIME)
INSERT INTO @Table1
VALUES (1,'2016-04-01',NULL),
(2,'2016-07-01',NULL)
INSERT INTO @Table2
VALUES (3,'2016-03-01','2016-04-01'),
(4,'2016-05-01','2016-06-01'),
(5,'2016-05-01','2016-06-02')
;WITH OrderedList AS
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY PeriodStart ORDER BY ModifiedDate DESC) AS MaxModified
FROM @Table2
),X AS
(
SELECT *,
ROW_NUMBER() OVER(ORDER BY PeriodStart) AS myID
FROM OrderedList
WHERE MaxModified=1
), Y AS
(
SELECT L.*, R.PeriodStart AS PeriodEnd
FROM X L
LEFT JOIN X R ON L.myID=R.myID-1 AND R.MaxModified=1
WHERE L.MaxModified=1
)
UPDATE T SET pK2=Y.pK2
FROM @Table1 T
LEFT JOIN Y ON T.PeriodStart >= Y.PeriodStart AND T.PeriodStart < COALESCE(Y.PeriodEnd,CURRENT_TIMESTAMP)
SELECT *
FROM @Table1