我需要有关此 SQL 查询的帮助。我有这张表,其中包含自 2020 年 7 月 1 日以来的每张发票。该表中有 CustomerID 和 InvoiceDt。对于每个 CustomerID,我需要知道交易是否有 18 个月的间隔,如果有,我需要最近 18 个月间隔之后的第一笔交易的日期
这就是我用作输入的表格的样子(我在代码中将其称为 m)
客户ID | 发票Dt |
---|---|
1 | '2020-1-2' |
1 | '2024-1-2' |
1 | '2024-2-2' |
2 | '2020-12-1' |
2 | '2021-12-1' |
2 | '2022-12-1' |
2 | '2023-12-1' |
2 | '2024-2-1' |
3 | '2024-2-12' |
这就是我想要的结果。客户 1 的第一次和第二次购买之间有 18 个月的间隔,因此我想要第二次购买的日期。客户 2 没有差距,所以我不希望它们包含在结果中。数据可以追溯到 2020 年 7 月 1 日,因此客户 3 开始时至少有 18 个月的间隔,所以我想要他们的第一个发票日期。我在代码中将此表称为 startDates
客户ID | 修改开始日期 |
---|---|
1 | '2024-1-2' |
3 | '2024-2-12' |
我能够在 python 中毫无问题地执行此操作,但我无法在不使用 SQL 中的循环的情况下仅在 groupby 中执行此操作
for cid in m.CustomerID.unique():
m1 = m[m.CustomerID== cid]
m1["InvShift"] = m1.InvoiceDt.shift(1)
m1["Gap"] = ((m1.InvoiceDt - m1.InvShift)/np.timedelta64(1, 'D')/30.42)
m1["18MonthGap"] = m1.Gap >= 18
if m1["18MonthGap"].sum() > 0:
startDates.ModStartDate.loc[cid] = m1[m1["18MonthGap"]].drop_duplicates("18MonthGap", keep="last").iloc[0].InvoiceDt
elif m1.iloc[0].InvoiceDt > pd.to_datetime("2022-1-1"):
startDates.ModStartDate.loc[cid] = m1.iloc[0].InvoiceDt
您使用 lag() 窗口函数,希望它在您的环境中可用。
select customer_id,invoice_dt
from
(select customer_id,invoice_dt
,lag(invoice_dt) over (partition by customer_id order by invoice_dt) prev_dt
from invoices
)
where months_between(invoice_dt,prev_dt) > 18
如果你没有months_ Between,你仍然应该有一些函数来计算两个日期之间的间隔。我希望你的日期确实是日期,而不是字符串,因为它们看起来可能是这样。
就您对客户 3 的要求而言。使用上面的查询的 UNION 可能最容易完成:
select customer_id,first_invoice
from
(Select customer_id,min(invoice_dt) first_invoice
from invoices
group by customer_id
)
where first_invoice > date'2022-01-01'