历史数据更新
History data update
我们需要检查 Auto Parking Membership activity。当个人成为会员时,详细信息最初将与 MemberID、MemberShipDate、ActivityDate、ActivityMonthEnd、IsActive、ActiveYTD 一起存储。此数据将存储到 DW table。这是我们存储到 DW 的 daily 数据。
最后一个字段“ActiveYTD”没有什么复杂的逻辑。默认值为‘Y’,该字段值取决于‘IsActive’字段。当 IsActive = ‘N’时,从 IsActive 字段值从 Y 变为 N 之日起,‘ActiveYTD’字段值也更新为‘N’。
但是有一个业务规则,这个 IsActive 字段可以是 Active 和 Inactive 任意次数。不知道为什么会有这样的规定
注意:- 如果假设 IsActive 字段值在 2022 年 2 月 15 日为“N”并且在 2022 年 4 月 20 日之前处于非活动状态。当然 ActivityYTD 字段也会从 Y 变为N 基于以上公式逻辑。但由于 IsActive 字段在 2022 年 4 月 21 日更改为“Y”。ActivityYTD 也将更改为“Y”。但业务定义是当 IsActive 字段从 N 更改为 Y 时。ActiveYTD 字段在前面的行中永远不应为“N”。从 2022 年 2 月 15 日至今的所有行都应为“Y”。因此,如果从 2022 年 2 月 15 日到年底的 IsActive 值 =“N”,则从 2022 年 2 月 15 日开始的 ActiveYTD 也将为“N”。
ActivityDate 和 ActivityMonthEndDate 都是来自维度 table 的键。 (例如:- 20220215、20220228)
基于上面定义的业务逻辑,我创建了一个查询
Select mainData.MemberID, mainData.MembershipDate, mainData.ActivityDateKey, mainData.ActivityMonthEndDateKey, InactiveData.InactiveDate, mainData.IsActive,
Case When mainData.IsAcitve =’N’ and (mainData.ActivityDateKey/100 >= InactiveData.InactiveDate/100) and (mainData.ActivityDateKey/10000 = InactiveData.InactiveDate/10000) then ‘Y’ else ‘N’ end as AcitveYTD
From History_AutoParkingMemberShip mainData
Left Outer Join
(
Select MemberID, Max(ActivityDateKey) as InactiveDate
From AutoParkinigMembership
Where IsActive = ‘N’
Group by MemberID
) InactiveData on InactiveData.MemberID = MainData.MemberID
但是这个查询并不是 100% 产生正确的结果。因为我还需要查找 IsActive 值 = ‘Y’ 时是否有任何情况,然后我更新 ActiveYTD 值‘Y’ 的先前值需要更新为‘N’。
MemberID MemberShipDate ActivityDateKey ActivityMonthEndDateKEy InactiveDate, IsActive ActiveYTD
1001 2019/06/17 20220101 20220131 Null Y Y
1001 2019/06/17 20220102 20220131 Null Y Y
... .... ... ... ... ... ...
1001 2019/06/17 20220201 20220228 Null Y Y
1001 2019/06/17 20220215 20220228 20220420 N N
... .... ... ... ... ... ...
1001 2019/06/17 20220420 20220430 20220420 N N
1001 2019/06/17 20220421 20220430 Null Y Y
1001 2019/06/17 20220422 20220430 Null Y Y
现在您看到上面的数据,其中 ActiveYTD 字段永远不应具有值 = 'N',因为该成员 1001 从 2022 年 4 月 21 日起再次活跃。这有点混乱。有人可以就如何改进查询提出您的想法吗?
您可以使用 Window 函数来做到这一点。
想法是找到按 ActivityDateKey 排序的那一年 'Y' 的最后一个 IsActive 值。
之前的任何行的 ActiveYTD 都应为 'Y'。
如果在最后一个 'Y' 之后有任何 IsActive='N' 的记录,请将其标记为 'N'.
下面的 Window 函数将给出 'Y' 的计数,直到当前行。
COUNT(CASE WHEN IsActive='Y' THEN 1 END)
OVER( PARTITION BY MemberID,ActivityDateKey/10000
ORDER BY ActivityDateKey Desc ROWS UNBOUNDED PRECEDING )
最终查询:
SELECT
tab.*
,CASE WHEN
COUNT(CASE WHEN IsActive='Y' THEN 1 END)
OVER( PARTITION BY MemberID,ActivityDateKey/10000
ORDER BY ActivityDateKey Desc ROWS UNBOUNDED PRECEDING ) >0 THEN 'Y' ELSE 'N' END ActiveYTD
FROM AutoParkinigMembership tab
ORDER BY ActivityDateKey
db<>fiddle: Try here
注意:以上fiddle是sqlserver-2014的,但在2012应该也能用。
数据集:
MemberID
MemberShipDate
ActivityDateKey
ActivityMonthEndDateKEy
IsActive
1001
2019-06-17
20220102
20220131
Y
1001
2019-06-17
20220201
20220228
Y
1001
2019-06-17
20220215
20220228
Y
1001
2019-06-17
20220420
20220430
N
1001
2019-06-17
20220421
20220430
Y
1001
2019-06-17
20220422
20220430
N
输出:
MemberID
MemberShipDate
ActivityDateKey
ActivityMonthEndDateKEy
IsActive
ActiveYTD
1001
2019-06-17
20220102
20220131
Y
Y
1001
2019-06-17
20220201
20220228
Y
Y
1001
2019-06-17
20220215
20220228
Y
Y
1001
2019-06-17
20220420
20220430
N
Y
1001
2019-06-17
20220421
20220430
Y
Y
1001
2019-06-17
20220422
20220430
N
N
我们需要检查 Auto Parking Membership activity。当个人成为会员时,详细信息最初将与 MemberID、MemberShipDate、ActivityDate、ActivityMonthEnd、IsActive、ActiveYTD 一起存储。此数据将存储到 DW table。这是我们存储到 DW 的 daily 数据。
最后一个字段“ActiveYTD”没有什么复杂的逻辑。默认值为‘Y’,该字段值取决于‘IsActive’字段。当 IsActive = ‘N’时,从 IsActive 字段值从 Y 变为 N 之日起,‘ActiveYTD’字段值也更新为‘N’。
但是有一个业务规则,这个 IsActive 字段可以是 Active 和 Inactive 任意次数。不知道为什么会有这样的规定
注意:- 如果假设 IsActive 字段值在 2022 年 2 月 15 日为“N”并且在 2022 年 4 月 20 日之前处于非活动状态。当然 ActivityYTD 字段也会从 Y 变为N 基于以上公式逻辑。但由于 IsActive 字段在 2022 年 4 月 21 日更改为“Y”。ActivityYTD 也将更改为“Y”。但业务定义是当 IsActive 字段从 N 更改为 Y 时。ActiveYTD 字段在前面的行中永远不应为“N”。从 2022 年 2 月 15 日至今的所有行都应为“Y”。因此,如果从 2022 年 2 月 15 日到年底的 IsActive 值 =“N”,则从 2022 年 2 月 15 日开始的 ActiveYTD 也将为“N”。 ActivityDate 和 ActivityMonthEndDate 都是来自维度 table 的键。 (例如:- 20220215、20220228) 基于上面定义的业务逻辑,我创建了一个查询
Select mainData.MemberID, mainData.MembershipDate, mainData.ActivityDateKey, mainData.ActivityMonthEndDateKey, InactiveData.InactiveDate, mainData.IsActive,
Case When mainData.IsAcitve =’N’ and (mainData.ActivityDateKey/100 >= InactiveData.InactiveDate/100) and (mainData.ActivityDateKey/10000 = InactiveData.InactiveDate/10000) then ‘Y’ else ‘N’ end as AcitveYTD
From History_AutoParkingMemberShip mainData
Left Outer Join
(
Select MemberID, Max(ActivityDateKey) as InactiveDate
From AutoParkinigMembership
Where IsActive = ‘N’
Group by MemberID
) InactiveData on InactiveData.MemberID = MainData.MemberID
但是这个查询并不是 100% 产生正确的结果。因为我还需要查找 IsActive 值 = ‘Y’ 时是否有任何情况,然后我更新 ActiveYTD 值‘Y’ 的先前值需要更新为‘N’。
MemberID MemberShipDate ActivityDateKey ActivityMonthEndDateKEy InactiveDate, IsActive ActiveYTD
1001 2019/06/17 20220101 20220131 Null Y Y
1001 2019/06/17 20220102 20220131 Null Y Y
... .... ... ... ... ... ...
1001 2019/06/17 20220201 20220228 Null Y Y
1001 2019/06/17 20220215 20220228 20220420 N N
... .... ... ... ... ... ...
1001 2019/06/17 20220420 20220430 20220420 N N
1001 2019/06/17 20220421 20220430 Null Y Y
1001 2019/06/17 20220422 20220430 Null Y Y
现在您看到上面的数据,其中 ActiveYTD 字段永远不应具有值 = 'N',因为该成员 1001 从 2022 年 4 月 21 日起再次活跃。这有点混乱。有人可以就如何改进查询提出您的想法吗?
您可以使用 Window 函数来做到这一点。
想法是找到按 ActivityDateKey 排序的那一年 'Y' 的最后一个 IsActive 值。
之前的任何行的 ActiveYTD 都应为 'Y'。 如果在最后一个 'Y' 之后有任何 IsActive='N' 的记录,请将其标记为 'N'.
下面的 Window 函数将给出 'Y' 的计数,直到当前行。
COUNT(CASE WHEN IsActive='Y' THEN 1 END)
OVER( PARTITION BY MemberID,ActivityDateKey/10000
ORDER BY ActivityDateKey Desc ROWS UNBOUNDED PRECEDING )
最终查询:
SELECT
tab.*
,CASE WHEN
COUNT(CASE WHEN IsActive='Y' THEN 1 END)
OVER( PARTITION BY MemberID,ActivityDateKey/10000
ORDER BY ActivityDateKey Desc ROWS UNBOUNDED PRECEDING ) >0 THEN 'Y' ELSE 'N' END ActiveYTD
FROM AutoParkinigMembership tab
ORDER BY ActivityDateKey
db<>fiddle: Try here
注意:以上fiddle是sqlserver-2014的,但在2012应该也能用。
数据集:
MemberID | MemberShipDate | ActivityDateKey | ActivityMonthEndDateKEy | IsActive |
---|---|---|---|---|
1001 | 2019-06-17 | 20220102 | 20220131 | Y |
1001 | 2019-06-17 | 20220201 | 20220228 | Y |
1001 | 2019-06-17 | 20220215 | 20220228 | Y |
1001 | 2019-06-17 | 20220420 | 20220430 | N |
1001 | 2019-06-17 | 20220421 | 20220430 | Y |
1001 | 2019-06-17 | 20220422 | 20220430 | N |
输出:
MemberID | MemberShipDate | ActivityDateKey | ActivityMonthEndDateKEy | IsActive | ActiveYTD |
---|---|---|---|---|---|
1001 | 2019-06-17 | 20220102 | 20220131 | Y | Y |
1001 | 2019-06-17 | 20220201 | 20220228 | Y | Y |
1001 | 2019-06-17 | 20220215 | 20220228 | Y | Y |
1001 | 2019-06-17 | 20220420 | 20220430 | N | Y |
1001 | 2019-06-17 | 20220421 | 20220430 | Y | Y |
1001 | 2019-06-17 | 20220422 | 20220430 | N | N |