SQL - 检查日期是否在另一列中的 14 天以内以及 return 最近的日期

SQL - check if a date is within 14d in another column and return the most recent date

我有一个包含以下列的数据集: user_id, A_view_dt, A_conversion_dt B_view_dt.

我想检查一下 如果 A_conversion_dt IS NOT NULL,则查看 B_view_dt 中是否有属于同一 user_id 的另一条记录发生在 A_conversion_dt 之前的 14 天,如果是 return B_view_dt 值。否则 return NULL 在 B_view_dt.

IF A_conversion_dt IS NULL,那么我想比较 A_view_dt 和 B_view_dt。如果 B_view_dt 记录存在并且发生在 14 天之前,则保留最近的 max(B_view_dt).

IF B_view_dt IS NULL 那么我想 B_view_dt 到 return NULL。

我附上了一个虚拟数据集和所需的输出。我一直在尝试使用 UNION ALL 和 LEFT JOIN,但 WHERE 子句中总是缺少记录。有人有更好的解决办法吗?在这种情况下使用分区有帮助吗?

谢谢!!!

See attachment here

select user_id,
    min(A_view_dt) as A_view_dt, min(A_conversion_dt) as A_conversion_dt,
    max(case when
        datediff(day, B_view_dt, coalesce(A_conversion_dt, A_view_dt)) between 0 and 14
            then B_view_dt end) as B_view_dt
from T
group by user_id

似乎可以安全地假设所有行(每个用户)在前两个日期列中具有相同的值,所以我 运行 在这个查询中。

https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=764c2857cc69190fca3fbd08de3e544c

或者您希望所有日期组合单独显示?:

select user_id, A_view_dt, A_conversion_dt,
    max(case when
        datediff(day, B_view_dt, coalesce(A_conversion_dt, A_view_dt)) between 0 and 14
            then B_view_dt end) as B_view_dt
from T
group by user_id, A_view_dt, A_conversion_dt

我怀疑是否有一种有效的方法 运行 这不需要一些预处理,特别是对于大型数据集。

基本上你需要2个虚拟数据集。

  • 唯一 user_id 和选择 conversion/view 日期。我们称之为 A_dt。在我的结果中,我添加了 cutoff 以帮助进行一些调试并使查询更简单。称之为 a
  • 唯一 user_idB_View_dt。称之为 b

Select 来自 a 的所有数据,然后在 cutoffA_dt.

范围内找到最大值 B_View_dt

使用t-sql,我使用CTE 来帮助创建虚拟表。请参阅 link 以测试解决方案 - http://sqlfiddle.com/#!18/4db34/5

  ;with a (user_id, A_dt, cutoff) as 
    (   
      select
        user_id,
        isnull(A_Conversion_dt,
        A_view_dt) A_dt,
        dateadd(d,-14, isnull(A_Conversion_dt,A_view_dt)) cutoff   
    from
        t   
    group by
        user_id,
        isnull(A_Conversion_dt,
        A_view_dt) 
    ), 
    b (user_id, B_dt) as 
    (
      select
        user_id,
        B_View_dt B_dt   
    from
        t     
    group by
        user_id,
        B_View_dt 
    ) 
    
    select
        a.*,
        MaxB_dt 
    from
        a 
    outer apply 
    (   
      select
        max(B_dt) MaxB_dt   
      from
            b    
      where
        a.user_id = b.user_id     
        and B_dt between cutoff and A_dt  
    ) ob

示例数据

查询结果