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_id
和 B_View_dt
。称之为 b
Select 来自 a
的所有数据,然后在 cutoff
和 A_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
示例数据
查询结果
我有一个包含以下列的数据集: 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_id
和B_View_dt
。称之为b
Select 来自 a
的所有数据,然后在 cutoff
和 A_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
示例数据
查询结果