【问题标题】:Create historicity dynamically动态创建历史性
【发布时间】:2020-03-26 17:36:21
【问题描述】:

我有这样一个问题:我需要计算客户动态更改日期范围的状态。

我有两种类型的客户:活跃的、不活跃的和丢失的。 活跃 - 3 年,不活跃 = 活跃 + 1 年,丢失 = 不活跃 + 1 年。例如,客户在 2018 年 3 月 3 日购买了产品。他活跃:03-03-2018:03-03-2021,不活跃:04-03-2021:03-03-2022,丢失 - 04-03-2022 当我输入 Period Start 和 Period End Date 时,我需要获取客户的当前状态。我想动态地创建历史性。

DECLARE @StartPeriod DATE = '2019-01-01';
DECLARE @EndPeriod DATE = '2019-11-23'; 

SELECT  @EndPeriod AS EndPeriod
    ,StartDate
    ,EndDate
    ,CustomerId
    ,ProductId
    ,CustomerType = CASE
    WHEN EndDate >=  @EndPeriod THEN 'Active'
    WHEN EndDate >= DATEADD(MONTH, -12, @EndPeriod)  AND EndDate < @EndPeriod
    THEN 'Inactive'
    WHEN EndDate <  EndPeriod THEN 'Lost'
    ELSE 'unknown' END
FROM Table
WHERE EndDate  between  @StartPeriod and @EndPeriod

条件WHERE EndDate between @StartPeriod and @EndPeriod 很糟糕,因为我没有得到所有数据。例如,客户是 Active-2016-11-24: 2019:11-24。使用我上面的范围,我没有得到这个客户,但他在那个时期很活跃。 怎么实现?

当我选择这样的范围时:

DECLARE @StartPeriod DATE = '2019-01-01';
DECLARE @EndPeriod DATE = '2019-11-24'; 

我得到这样的结果(而且是正确的):

当我选择这样的范围时:

DECLARE @StartPeriod DATE = '2019-01-01';
DECLARE @EndPeriod DATE = '2019-11-23'; 

我得到一个空的结果。但是客户是活跃的(这是因为Where 条件错误)。

不同的客户有不同的End Date。但我需要知道每个选定时期的状态。我不知道如何实施这种情况。

【问题讨论】:

  • 请以表格文本的形式提供示例数据和预期结果。
  • 每个人都有结束日期吗?您可能需要在该范围内指定结束日期,或者不存在结束日期。
  • 您需要提供数据样本
  • 我在上面的主题中提供了一个例子

标签: sql-server tsql


【解决方案1】:

您不能在此示例中使用 between,因为如您所见,EndDate 可能在您感兴趣的期间之外。相反,您需要检查 EndDate&gt;= 期间的开始您对AND感兴趣,StartDate&lt;=你感兴趣的期末。你可能需要玩一下是&gt;=&&lt;=,还是&gt;&&lt;或根据您要如何处理边缘情况来组合。

我也处理了EndDate 为空的情况。

declare @Table table (id int, StartDate date, EndDate date, CustomerId int, ProductId int)

insert into @Table (id, CustomerId, ProductId, StartDate, EndDate)
values (1, 1, 1, '2016-11-24', '2019-11-24')

declare @StartPeriod date = '2019-01-01', @EndPeriod date = '2019-11-23'; 

select @EndPeriod as EndPeriod
    , StartDate
    , EndDate
    , CustomerId
    , ProductId
    , CustomerType = case
    when EndDate >=  @EndPeriod then 'Active'
    when EndDate >= dateadd(month, -12, @EndPeriod)  AND EndDate < @EndPeriod then 'Inactive'
    when EndDate < @EndPeriod then 'Lost'
    else 'unknown' end
from @Table
-- where EndDate between @StartPeriod and @EndPeriod
where StartDate <= @EndPeriod and (EndDate isnull or EndDate >= @StartPeriod)

请注意我如何设置数据以使用表变量进行测试。如果你对未来的问题做类似的事情,你会很快得到答案,因为你让别人回答变得尽可能容易。

【讨论】:

    猜你喜欢
    • 2013-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-28
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    • 2013-04-08
    相关资源
    最近更新 更多