遍历日期列表(或任何列表)并在 mysql 或 snowflake 中附加查询

loop over a date list (or any list) and append queries in mysql or snowflake

我是 sql 语言的新手,最近才接触 snowflake。我有一个 table,其中包含企业所有用户的所有签到日期

user_id | checkin_date
001       03-06-2018
001       07-07-2018
001       08-01-2018
002       03-19-2018
002       03-27-2018
002       07-11-2018

现在我想做一个查询,这样我就可以从 query_date 回顾每个用户在 query_date - 7 和 query_date 之间签到的次数,qyery_date - 90 和查询日期...以下雪花查询可以正确完成 query_date='2018-08-01' 的工作。

with user_checkin_history_sum as (
select 
  user_id,
  sum(iff(datediff(DAY, uc.checkin_date, '2018-08-01') <= 7, 1, 0)) as visits_past_7_days,
  sum(iff(datediff(DAY, uc.checkin_date, '2018-08-01') <= 90, 1, 0)) as visits_past_90_days,
from user_checkin as uc
where uc.checkin_date < '2018-08-01'
group by user_id
order by user_id
)

这给了我结果

user_id | visits_past_7_days | visits_past_90_days
001       0                    2
002       0                    1

我的问题是,如果我有超过一天的 query_date,即我有一个 checkin_date 的列表,对于列表中的每个 checkin_date,我做上面的查询并将它们附加在一起。基本上,它是一个循环 + table 附加,但我没有找到如何用 sql 语言执行此操作的答案。本质上,我想做的是像下面这样

with user_checkin_history_sum as (
select 
  user_id,
  sum(iff(datediff(DAY, uc.checkin_date, query_date) <= 7, 1, 0)) as visits_past_7_days,
  sum(iff(datediff(DAY, uc.checkin_date, query_date) <= 90, 1, 0)) as visits_past_90_days,
from user_checkin as uc
where uc.checkin_date < query_date and
LOOP OVER
    query_date in ('2018-08-01', '2018-06-01')
group by user_id
order by user_id
)

希望它能给出这个结果

user_id | query_date | visits_past_7_days | visits_past_90_days
001      '08-01-2018'  0                    2
002      '08-01-2018'  0                    1
001      '06-01-2018'  0                    1
002      '06-01-2018'  0                    2

您应该能够交叉加入包含您要检查的所有日期的 table:

WITH dates AS (
    SELECT '2018-06-01' AS query_date UNION ALL
    SELECT '2018-08-01' UNION ALL
    ...     -- maybe other dates as well
),
user_checkin_history_sum AS (
    SELECT
        uc.user_id,
        d.query_date,
        SUM(IFF(DATEDIFF(DAY, uc.checkin_date, d.query_date) <= 7, 1, 0)) AS visits_past_7_days,
        SUM(IFF(DATEDIFF(DAY, uc.checkin_date, d.query_date) <= 90, 1, 0)) AS visits_past_90_days
    FROM dates d
    CROSS JOIN user_checkin AS uc
    WHERE uc.checkin_date < '2018-08-01'
    GROUP BY d.query_date, uc.user_id
    ORDER BY d.query_date, uc.user_id
)