我有一张表activity
,如下所示:
date | user_id |
成千上万的用户以及所有这些用户的多个日期和活动。我想提取一个查询,该查询将在结果中的每一天为我提供过去30天内的活跃用户总数。我现在的查询如下所示:
select date, count(distinct user_id) from activity where date > date_sub(date, interval 30 day) group by date
这仅在当天为我提供了完全独特的用户;我不能让它给我每个日期的最后30个。感谢帮助。
答案 0 :(得分:1)
要执行此操作,您需要一个日期列表,并将其与活动结合起来。
因此,这应该做到这一点。获取日期列表然后计数user_id的子查询(或者您可以使用COUNT(*),因为我假设user_id不能为空): -
SELECT date, COUNT(user_id)
FROM
(
SELECT DISTINCT date, DATE_ADD(b.date, INTERVAL -30 DAY) AS date_minus_30
FROM activity
) date_ranges
INNER JOIN activity
ON activity.date BETWEEN date_ranges.date_minus_30 AND date_ranges.date
GROUP BY date
但是,如果在任何特定日期可能有多个user_id记录,但您只需要在日期上计算唯一user_id,则需要计算DISTINCT user_id(但请注意,如果用户ID出现在2个不同的日期内) 30天的日期范围,他们只计算一次): -
SELECT activity.date, COUNT(DISTINCT user_id)
FROM
(
SELECT DISTINCT date, DATE_ADD(b.date, INTERVAL -30 DAY) AS date_minus_30
FROM activity
) date_ranges
INNER JOIN activity
ON activity.date BETWEEN date_ranges.date_minus_30 AND date_ranges.date
GROUP BY date
根据日期范围加入活动表并使用COUNT(DISTINCT ...)来消除重复项有点粗糙: -
SELECT a.date, COUNT(DISTINCT a.user_id)
FROM activity a
INNER JOIN activity b
ON a.date BETWEEN DATE_ADD(b.date, INTERVAL -30 DAY) AND b.date
GROUP by a.date