SQL Server 获取第一个日期或间隔后的第一个日期

e3bfsja2  于 2023-01-12  发布在  其他
关注(0)|答案(2)|浏览(152)

我有一个很大的客户表,他们的策略是这样设置的(实际日期可以是全年的):
| 记录|客户ID|姓名|策略开始|策略结束|代理人|现况|
| - ------|- ------|- ------|- ------|- ------|- ------|- ------|
| 1个|小行星123|无名氏|小行星2006|小行星2008|约翰·史密斯|期限|
| 第二章|小行星123|无名氏|小行星2009|小行星2010|鲍秀华|期限|
| 三个|小行星123|无名氏|小行星20110101||鲍秀华|活跃|
| 四个|小行星12346|邋遢乔|小行星2013|小行星2014|李柏立|期限|
| 五个|小行星12346|邋遢乔|小行星20||李柏立|活跃|
我一直在使用一个基本的SQL查询来获取所有活动帐户,方法是选择状态为"活动"的记录,并显示活动策略的列表,如下所示:

SELECT * FROM Customers WHERE Status = 'Active'

| 记录|客户ID|姓名|策略开始|策略结束|代理人|现况|
| - ------|- ------|- ------|- ------|- ------|- ------|- ------|
| 三个|小行星123|无名氏|小行星20110101||鲍秀华|活跃|
| 五个|小行星12346|邋遢乔|小行星20||李柏立|活跃|
然而,我现在被要求提供这样一个结果:
| 记录|客户ID|姓名|原始生效日期|代理人|现况|
| - ------|- ------|- ------|- ------|- ------|- ------|
| 三个|小行星123|无名氏|小行星2006|鲍秀华|活跃|
| 五个|小行星12346|邋遢乔|小行星20|李柏立|活跃|
具体的任务是使用以下条件根据策略开始日期和结束日期计算OriginalEffectiveDate列:* * 只要保险范围没有中断一个月或更长时间,就使用最早的保单开始日期作为客户的OriginalEffectiveDate。如果存在间隔,则使用最新间隔之后的第一个日期。**
因此,Jane的原始有效日期将是20060101,因为这是她首次获得保险的日期,并且她的保险没有任何中断。但是,Joe的原始有效日期将是20200101,因为他在初始保单之后有一个中断(一个月或更长时间),并且这是缺口之后的第一个日期。
我试过乱用CASE、MIN、MAX和TOP语句,但都无济于事。我不知道该如何继续。我相信"授人以渔",所以请随时为我指出教程的方向。症结在于"一个月或更长时间"和"最新差距之后"部分。我试着在网上搜索解决方案,但我没有遇到类似的东西,但也许我不知道该怎么表达这个问题。

4jb9z9bj

4jb9z9bj1#

您可以尝试的一个可能的解决方案是使用 lag
首先获得当前PolicyEnd和下一个PolicyStart之间的间隔月数,然后可以找到间隔大于1个月的每个客户的最新记录。
然后,您可以选择此点 * 之后 * 每个客户的最小有效记录。

with gaps as (
  select *,
    case when DateDiff(month, PolicyEnd,Lead(PolicyStart) over(partition by CustomerID order by Record)) > 1 then 1 else 0 end b
  from t
), minrecord as (
  select CustomerID, Max(Record) mr
  from gaps
  where b = 1
  group by CustomerID
)
select Record, CustomerID, [Name], Agent, [Status], ed.OriginialEffectiveDate
from t
cross apply (
  select Min(PolicyStart) OriginialEffectiveDate
  from t t2
  where t2.CustomerID = t.CustomerID and
    t2.Record > IsNull((select mr from minrecord where CustomerID = t2.CustomerID), 0)
)ed
where t.[Status] = 'active';

查看此demo Fiddle

inb24sb2

inb24sb22#

以下是我最终的结论:

SELECT Record
    ,Customers.CustomerID
    ,Name
    ,CustomerEffectiveDate
    ,Agent
    ,Status
FROM Customers
JOIN (
    SELECT CustomerID
        ,MIN(PolicyStart) AS CustomerEffectiveDate
    FROM (
        SELECT CustomerID
            ,PolicyStart
            ,DateDiff(month, PolicyEnd, Lead(PolicyStart) OVER (
                    PARTITION BY CustomerID ORDER BY CustomerID
                        ,PolicyStart
                    )) AS gapMonths
        FROM Customers
        ) gaps
    WHERE gapMonths < 2
        OR gapMonths IS NULL
    GROUP BY CustomerID
    ) minstart ON customers.CustomerID = minstart.CustomerID
WHERE status = 'Active'

这可能不是最有效的代码,但似乎可以工作。

相关问题