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

如何用Snowflake SQL/Snowpark/Pandas筛选连续12个月有数据的ID

筛选过去12个连续月份均有销售数据的ID实现方案

示例数据

idsalessales_date_monthend
152023-05-31
1102023-04-30
1112023-03-31
1122023-02-27
112023-01-31
152022-12-31
132022-11-30
162022-10-31
192022-09-30
182022-08-31
172022-07-31
132023-06-30
122023-05-31
282022-08-31
272022-07-31
232023-06-30
222023-05-31

需求说明

筛选出过去12个连续月份均有销售数据的id(即每个月都存在对应数据)。例如id=1每月都有销售记录,但id=2缺失部分月份的数据。


Snowflake SQL实现

先生成过去12个连续月份的月末日期,关联去重后的销售数据,统计每个id覆盖的月份数,筛选出覆盖全部12个月的id:

-- 生成过去12个连续月份的月末日期
WITH required_months AS (
    SELECT LAST_DAY(DATEADD(MONTH, -seq8(), DATE_TRUNC('MONTH', CURRENT_DATE)))::DATE AS monthend
    FROM TABLE(GENERATOR(ROWCOUNT => 12))
),
-- 去重同一id同一月份的销售记录,避免重复计数
unique_sales AS (
    SELECT DISTINCT id, sales_date_monthend
    FROM sample_table
)
SELECT id
FROM required_months
LEFT JOIN unique_sales ON required_months.monthend = unique_sales.sales_date_monthend
GROUP BY id
HAVING COUNT(unique_sales.sales_date_monthend) = 12;

Snowpark实现

利用Snowpark DataFrame API,构建全量id-月份组合,左连接销售数据后统计缺失月份数,筛选无缺失的id:

from snowflake.snowpark import Window
import snowflake.snowpark.functions as F

# 生成过去12个连续月份的月末日期
date_range = session.sql("""
    SELECT LAST_DAY(DATEADD(MONTH, -seq8(), DATE_TRUNC('MONTH', CURRENT_DATE)))::DATE AS monthend
    FROM TABLE(GENERATOR(ROWCOUNT => 12))
""")

# 读取原表并去重id和月份
sample_table = session.table("sample_table").select("id", "sales_date_monthend").distinct()

# 生成每个id对应所有12个月份的组合
all_id_months = sample_table.select("id").distinct().crossJoin(date_range)

# 左连接销售数据,统计每个id的缺失月份数
joined = all_id_months.join(
    sample_table, 
    (all_id_months["id"] == sample_table["id"]) & 
    (all_id_months["monthend"] == sample_table["sales_date_monthend"]),
    how="left"
)

result = joined.group_by("id") \
               .agg(F.count(F.when(F.col("sales_date_monthend").is_null(), 1)).alias("missing_months")) \
               .filter(F.col("missing_months") == 0) \
               .select("id")

# 输出结果
result.show()

Pandas实现

本地处理时,统一日期格式后,检查每个id的月份集合是否包含过去12个连续月份:

import pandas as pd
from datetime import datetime
from dateutil.relativedelta import relativedelta

# 读取示例数据(实际可从Snowflake导入)
data = [
    [1,5,"2023-05-31"],[1,10,"2023-04-30"],[1,11,"2023-03-31"],[1,12,"2023-02-27"],
    [1,1,"2023-01-31"],[1,5,"2022-12-31"],[1,3,"2022-11-30"],[1,6,"2022-10-31"],
    [1,9,"2022-09-30"],[1,8,"2022-08-31"],[1,7,"2022-07-31"],[1,3,"2023-06-30"],
    [1,2,"2023-05-31"],[2,8,"2022-08-31"],[2,7,"2022-07-31"],[2,3,"2023-06-30"],
    [2,2,"2023-05-31"]
]
df = pd.DataFrame(data, columns=["id", "sales", "sales_date_monthend"])

# 统一日期格式为月末标准格式
df["sales_date_monthend"] = pd.to_datetime(df["sales_date_monthend"]).dt.to_period('M').dt.to_timestamp('M')

# 生成过去12个连续月份的月末集合
current_month = datetime.now().replace(day=1)
required_months = {current_month - relativedelta(months=i) for i in range(12)}

# 筛选符合条件的id
valid_ids = []
for id_, group in df.groupby("id"):
    id_months = set(group["sales_date_monthend"])
    if required_months.issubset(id_months):
        valid_ids.append(id_)

print("符合条件的id:", valid_ids)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 21:02:09