我有两个表– purchases
和activity
。
purchase
表的结构如下:
|----------|----------------|----------|
| user_id | purchase_date | status |
|----------|----------------|----------|
| 1234 | 2020-01-01 | active |
|----------|----------------|----------|
| 2345 | 2020-01-10 | cancelled|
activity
表的结构如下:
|----------|----------------|-----------------|
| user_id | date | videos_viewed |
|----------|----------------|-----------------|
| 1234 | 2020-01-02 | 4 |
|----------|----------------|-----------------|
| 2345 | 2020-01-03 | 3 |
|----------|----------------|-----------------|
| 2345 | 2020-01-10 | 10 |
|----------|----------------|-----------------|
| 2345 | 2020-01-11 | 7 |
我希望根据设定的购买期限为每个用户的前30天查询前30天的活动平均值。
到目前为止我写的查询是这样的:
SELECT avg(t3.viewsperday)
FROM
(SELECT
date
,sum(t1.videos_viewed)/count(t1.user_id) as viewsperday
FROM activity t1
INNER JOIN (SELECT * FROM purchase c
WHERE status = 'active'
AND purchase_date BETWEEN '2020-01-01' and '2020-02-01') t2
ON t1.user_id = t2.user_id
where date between '2020-01-01' and '2020-02-01'
group by 1
order by 1 asc) as t3;
但是,这里的问题是,如果用户在2020-01-31
上购物,那么我只会得到第一天的活动。我需要帮助来弄清楚如何获得滚动平均值/从每个购买日期起30天前-以及从这30天中获取平均活动。
我怀疑此处适合使用窗口函数,但是由于它有点超出我的知识范围,因此我不确定如何编写它。任何帮助将不胜感激。
答案 0 :(得分:1)
以下应能工作。我假设即使在某些日子里的观看次数为零,您也希望获得30天以上的平均值?您可能还需要根据确切地定义30天日期范围的方式(即包含30天,包含购买日期等)进行稍微调整。 我将其写为外部联接,这样即使没有视图的用户也将被包括在内
SELECT
P.USER_ID,
SUM(A.VIDEOS_VIEWED)/30
FROM PURCHASE P
LEFT OUTER JOIN ACTIVITY A ON P.USER_ID = A.USER_ID AND
A.DATE >= P.PURCHASE_DATE AND A.DATE <= dateadd(DAY, 30, P.PURCHASE_DATE)
GROUP BY P.USER_ID;
更新... 要获取每日平均值,请尝试以下操作(购买日期的视图显示为第0天,如果应将第1天设为1,则将其添加到Day_after_Purchase公式中):
SELECT
(a.date - p.purchase_date) as Day_after_Purchase,
avg(A.VIDEOS_VIEWED)
FROM PURCHASE P
LEFT OUTER JOIN ACTIVITY A ON P.USER_ID = A.USER_ID AND
A.DATE >= P.PURCHASE_DATE AND A.DATE <= dateadd(DAY, 30, P.PURCHASE_DATE)
GROUP BY 1;