You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

每行时间窗口不同时如何编写单SQL查询实现回溯聚合构建客户流失预测数据集

完全可以用单条SQL批量完成所有计算,性能会比逐行查询高几个量级。

核心思路

你之前逐行查询的逻辑本质是对每一行的account_no和ExtractDate,匹配符合区间条件的服务数。我们可以直接把待计算的所有行作为主表,和全量服务表做关联聚合,一次性算出所有结果。

具体实现

分两种场景处理:

场景1:待计算的数据集已经存储在数据库中

假设你的待计算表名为service_labels,包含account_no、service_no、ExtractDate三个关键字段,直接执行以下查询即可:

SELECT 
    t.account_no,
    t.service_no,
    t.ExtractDate,
    COUNT(DISTINCT s.ServiceNo) AS active_service_cnt
FROM service_labels t
LEFT JOIN ServicesAll s 
    ON t.account_no = s.AccountNo
    AND s.InstallationDate < t.ExtractDate
    AND (s.BillingStopDate IS NULL OR s.BillingStopDate >= t.ExtractDate)
GROUP BY t.account_no, t.service_no, t.ExtractDate

场景2:待计算的数据集仅存在于Python的DataFrame中

你可以先把需要用的字段批量写入数据库临时表,再执行关联查询,代码示例如下:

# 将待计算的关键字段写入临时表
iter_df[["account_no", "service_no", "ExtractDate"]].to_sql(
    name="temp_calc_labels",
    con=conn,
    if_exists="replace",
    index=False
)
# 执行批量计算查询
calc_sql = """
SELECT 
    t.account_no,
    t.service_no,
    t.ExtractDate,
    COUNT(DISTINCT s.ServiceNo) AS active_service_cnt
FROM temp_calc_labels t
LEFT JOIN ServicesAll s 
    ON t.account_no = s.AccountNo
    AND s.InstallationDate < t.ExtractDate
    AND (s.BillingStopDate IS NULL OR s.BillingStopDate >= t.ExtractDate)
GROUP BY t.account_no, t.service_no, t.ExtractDate
"""
# 读取计算结果并合并回原数据集
result_df = pd.read_sql(calc_sql, conn)
final_df = iter_df.merge(
    result_df,
    on=["account_no", "service_no", "ExtractDate"],
    how="left"
)

性能优化建议

给ServicesAll表建立(AccountNo, InstallationDate, BillingStopDate)联合索引,可以进一步大幅降低查询耗时。

结果验证

上述SQL的筛选逻辑和你原有的逐行查询逻辑完全一致,计算结果和你之前逐行遍历得到的结果完全相同,你可以拿示例中的S1、S3记录核对数值。

内容的提问来源于stack exchange,提问作者ddd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 07:54:02