我有一个包含日期和用户的表"Days_Users"(每个日期和用户占一行),从中我可以提取特定日期或特定日期显示用户的信息:

2023-01-01,user1
2023-01-01,user2
2023-01-01,user3
2023-01-02,user2
2023-01-02,user4
2023-01-03,user1
2023-01-03,user4

我需要计算每天有多少新用户出现/消失,但我不知道怎么做.在某一天出现的用户是指当天看到该用户,但之前从未见过该用户,而在某一天出现的用户是指在该天看到该用户,但在该日期之后再也没有人看到该用户.

我认为开始的方法是创建一个用户视图,First_Date_Seed,Last_Date_Seed,如下所示:

user_first_last AS (
SELECT user, min(date) AS first_date_seen, max(date) AS last_date_seen FROM days_users
GROUP BY 1
)

然后计算从特定日期到结束为止出现的所有用户

SELECT date, COUNT(DISTINCT user) as num_appearing_users 
FROM user_first_last WHERE first_date_seen = {date} AND last_date_seen = '2023-03-01' 
GROUP BY 1
ORDER BY 1

对于正在消失的用户也是如此

SELECT date, COUNT(DISTINCT user) as num_disappearing_users 
FROM user_first_last WHERE first_date_seen = '2023-01-01' AND last_date_seen = {date} 
GROUP BY 1
ORDER BY 1

但请注意大括号中的{date}:我希望此日期与查询中的日期相同,即粗体显示的两个日期应该相同:

SELECT 
    **date**, COUNT(DISTINCT user) AS num_disappearing_users 
FROM user_first_last 
WHERE first_date_seen = '2023-01-01' 
  AND last_date_seen = **date** 

我怎样才能做到这一点呢?

推荐答案

您可以执行以下操作:

with dates as(
select distinct date from days_users),
usg as (
  select min(date) first_date,
    max(date) last_date,
    user
    from days_users
    GROUP BY user
)
select date,
  (select count(user)
   from usg
   where usg.last_date=dates.date
  ) never_seen_after,
  (select count(user)
   from usg
   where usg.first_date=dates.date
  ) never_seen_before
from dates 

这里我们使用CTE:

  • dates-要获取数据中存在的日期列表,
  • usg-第一天和最后一天的用户列表.

Sql相关问答推荐

如何在SQL查询中只比较日期时间的年份和月份(而忽略日期比较)?

SUM(条件)在Oracle?

Group By子句返回太多行

基于前面行的值:当x&>2时重复1,当连续3行x=0时则重复0

部分匹配表中元素的MariaDB查询查找结果

使用DatePart函数对日期时间值进行分组

用户购买平台及金额统计

如何将`now()`作为SQL插入语句的一部分?

在Netezza SQL中将字符DataType转换为整型DataType

无法访问级联删除导致的触发器中已删除的外键记录

同时插入和更新记录

使用 XML 作为 SQL 表

列(值不为空)到其他有序列

Clickhouse:左连接表到外部数组

SQL 多个不满足的条件失败

Postgres更新增量之间的差异

根据潜在空值的条件对记录进行计数

我需要遍历权重值表并确定每个权重是否有效

SQL查询以获取从特定可变日期看到的用户

从不同的表中 Select 包含单词列表的记录