首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >窗口函数需要分组依据,但是为什么呢?

窗口函数需要分组依据,但是为什么呢?
EN

Stack Overflow用户
提问于 2021-10-08 02:29:58
回答 2查看 71关注 0票数 1

我有一个电子商务,并想衡量60天后的第一次销售留存率。留存用户在接下来的60天内至少进行了一次购买。

我有一个包含以下信息的sales表:

代码语言:javascript
复制
Sale ID | Customer ID | Date
1       |  405        | 2021-03-05
2       |  408        | 2021-03-06
3       |  231        | 2021-03-07

我对计算留存率的部分有问题。

我尝试使用这个查询:

代码语言:javascript
复制
SELECT
         "Customer ID",
         COUNT("Sale ID") OVER(
            PARTITION BY "Customer ID"
            ORDER BY "Date" ASC
            RANGE BETWEEN CURRENT ROW AND INTERVAL '60 days' FOLLOWING
            ) AS "60 days Sales"
            
         FROM "Sales"
      GROUP BY "Customer ID"

在尝试之后,我得到了这个错误:ERROR: Column "Date" must appear in the GROUP BY clause or be used in aggregate

我希望该查询能够获得任何给定客户在这60天内完成的销售数量。这样,我可以在以后使用它,并将客户过滤为保留或流失。

我做错了什么?我不确定为什么要将"Date“分组:我希望结果按客户ID分组。

谢谢!

EN

回答 2

Stack Overflow用户

发布于 2021-10-08 06:14:02

问题是窗口函数是在GROUP BY之后求值的,所以PostgreSQL不知道你指的是一个组中的哪个"Date"

您可能应该使用过滤聚合,而不是窗口函数。我不确定您到底想要查询什么,但可能是类似于下面的内容:

代码语言:javascript
复制
SELECT "Customer ID",
       COUNT("Sale ID")
          FILTER (WHERE "Date" BETWEEN current_timestamp
                               AND current_timestamp + INTERVAL '60 days')
          AS "60 days Sales"
FROM "Sales"
GROUP BY "Customer ID";
票数 1
EN

Stack Overflow用户

发布于 2021-10-08 02:45:51

代码语言:javascript
复制
select "Customer ID",
    case when max("60 days Sales") > 1 then 'Retained' else 'Churned' end as Status
from (
    SELECT
        "Customer ID",
        COUNT("Sale ID") OVER(
            PARTITION BY "Customer ID"
            ORDER BY "Date" ASC
            RANGE BETWEEN CURRENT ROW AND INTERVAL '60 days' FOLLOWING
        ) AS "60 days Sales"            
    FROM "Sales"
) t
group by "Customer ID"

首先看一下每一笔交易。然后决定该客户是否有符合您60天条件的销售。如果你的逻辑要求专注于最初的销售,那么你必须做一些不同的事情,比如:

代码语言:javascript
复制
select "Customer ID",
    case when count(case when "Date" > firstDate then 1 end) > 0 then 'Retained' else 'Churned' end as Status
from (
    SELECT
        "Customer ID", "Date",
        min("Date") over (partition by "Customer ID") AS firstSale            
    FROM "Sales"
) t
where "Date" between firstSale and firstDate + interval '60 days'
group by "Customer ID"

目前还不清楚是否有可能在最初的日期出售两笔交易,也不清楚你会如何看待这一点。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69489804

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档