雪花查询将一行与所有前一行进行比较
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
我有如下数据集。
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 |