雪花查询将一行与所有前一行进行比较

snowflake query to compare a row with all the previous row

我有如下数据集。

ID Date
100 2022-03-01
100 2022-02-10
100 2021-12-15
100 2021-11-30
200 2021-08-05
200 2021-07-10

对于特定的 ID,我需要比较之前的行以检查它们是否存在于之前的月份中。所以我的输出 table 应该如下所示:

ID Date 1MonthAgo 2MonthAgo 3MonthAgo
100 2022-03-01 1 0 1
100 2022-02-10 0 1 1
100 2021-12-15 1 0 0
100 2021-11-30 0 0 1
200 2021-08-05 1 0 0
200 2021-07-10 0 0 0

我可以使用 LAG 函数,但我认为它以前只适用于一行。对于特定的 ID,我需要回顾 3 个月的 ID 是否存在。不需要做任何天数计算,一个月就可以了。

有什么方法可以使用 sql 实现此目的吗? 感谢对此的任何帮助。 谢谢

以下仅根据月份计算 -

实际table-

select * from PREV_MONTH;
+-----+------------+
|  ID | DT_DATE    |
|-----+------------|
| 100 | 2022-03-01 |
| 100 | 2022-02-10 |
| 100 | 2021-12-15 |
| 100 | 2021-11-30 |
| 200 | 2021-08-05 |
| 200 | 2021-07-10 |
+-----+------------+

查询以绘制所需结果 -

select id,dt_date,
CASE
when extract(month from add_months(dt_date,-1)) 
IN 
(select extract (month from dt_date) FROM 
prev_month pm1 where pm1.id=prev_month.id)
    then 1
    else 0 end as month_1,
    CASE
    when extract(month from add_months(dt_date,-2)) 
IN 
(select extract (month from dt_date) FROM 
prev_month pm1 where pm1.id=prev_month.id)
    then 1
    else 0 end as month_2,
    CASE
    when extract(month from add_months(dt_date,-3)) 
IN 
(select extract (month from dt_date) FROM 
prev_month pm1 where pm1.id=prev_month.id)
    then 1
    else 0 end as month_3
    from prev_month;
+-----+------------+---------+---------+---------+
|  ID | DT_DATE    | MONTH_1 | MONTH_2 | MONTH_3 |
|-----+------------+---------+---------+---------|
| 100 | 2022-03-01 |       1 |       0 |       1 |
| 100 | 2022-02-10 |       0 |       1 |       1 |
| 100 | 2021-12-15 |       1 |       0 |       0 |
| 100 | 2021-11-30 |       0 |       0 |       0 |
| 200 | 2021-08-05 |       1 |       0 |       0 |
| 200 | 2021-07-10 |       0 |       0 |       0 |
+-----+------------+---------+---------+---------+

因此使用此 CTE 数据:

with data(ID, DT_DATE) as (
    SELECT * FROM VALUES
        (100, '2022-03-01'),
        (100, '2022-02-10'),
        (100, '2021-12-15'),
        (100, '2021-11-30'),
        (200, '2021-08-05'),
        (200, '2021-07-10')
)

每个日期的前一个月 window:

如果您想知道每一行的“从该日期起的第 1、2、3 个月 window 中有 1 个以上的值”,这个超级非高性能代码就可以工作。

SELECT 
    a.id
    ,a.dt_date
    ,count_if(b.dt_date >= dateadd('month',-1, a.dt_date) and b.dt_date < dateadd('month', 0, a.dt_date))::int as "1monthago"
    ,count_if(b.dt_date >= dateadd('month',-2, a.dt_date) and b.dt_date < dateadd('month', -1, a.dt_date))::int as "2monthago"
    ,count_if(b.dt_date >= dateadd('month',-3, a.dt_date) and b.dt_date < dateadd('month', -2, a.dt_date))::int as "3monthago"
FROM data AS a
LEFT JOIN data AS b 
    ON a.id = b.id AND b.dt_date < a.dt_date
GROUP BY 1,2
ORDER BY 1,2 desc;
ID DT_DATE 1monthago 2monthago 3monthago
100 2022-03-01 1 0 1
100 2022-02-10 0 1 1
100 2021-12-15 1 0 0
100 2021-11-30 0 0 0
200 2021-08-05 1 0 0
200 2021-07-10 0 0 0

之前命名的月份:

SELECT 
    a.id
    ,a.dt_date
    ,count_if(date_trunc('month', dateadd('month',-1, a.dt_date)) = date_trunc('month', b.dt_date))::int as "1monthago"
    ,count_if(date_trunc('month', dateadd('month',-2, a.dt_date)) = date_trunc('month', b.dt_date))::int as "2monthago"
    ,count_if(date_trunc('month', dateadd('month',-3, a.dt_date)) = date_trunc('month', b.dt_date))::int as "3monthago"
FROM data AS a
LEFT JOIN data AS b 
    ON a.id = b.id AND b.dt_date < a.dt_date
GROUP BY 1,2
ORDER BY 1,2 desc;
ID DT_DATE 1monthago 2monthago 3monthago
100 2022-03-01 1 0 1
100 2022-02-10 0 1 1
100 2021-12-15 1 0 0
100 2021-11-30 0 0 0
200 2021-08-05 1 0 0
200 2021-07-10 0 0 0