假设你有一个像这样的表:
CREATE TABLE `checkins` (
`id` bigint(20) NOT NULL default '0',
`userid` bigint(20) default NULL,
`timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `ind_userid` (`userid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
根据日期范围,如何确定每周3-5天有多少用户活动。
像
这样的东西input - two months date range
output - 310 users were active 3-5 days a week
答案 0 :(得分:1)
如果您创建一个每周一行的日历表,您应该可以通过以下查询解决问题:
SELECT userid
FROM (SELECT userid,
YEARWEEK(TIMESTAMP) AS year_week,
COUNT(DISTINCT DAYOFWEEK(TIMESTAMP)) AS check_in_days
FROM checkins
WHERE 1 = 1 -- This would be your date range filter
GROUP BY userid,
YEARWEEK(TIMESTAMP)
HAVING check_in_days BETWEEN 3 AND 5) AS user_weeks
GROUP BY userid
HAVING COUNT(year_week) = (SELECT COUNT(*)
FROM year_week
WHERE 1 = 1 -- This would be your date range filter
);
(我的周表在2001年到2020年之间每周有一行。)
内部查询(user_weeks)为每个{user_id,week}返回一行,其中用户在该特定周内至少3天或最多5天签到。 (每天签到的Nr无关紧要)。外部查询为每个{user_id}返回一行,以及满足3-5天签到要求的周数。 外部选择中的having子句过滤结果,仅包括已签入多次(周)的用户作为日期范围内的实际周数。这应该照顾“连续”的周要求。
如果这有助于您,请告诉我。
修改强> 从功能周()更改为年周()。
答案 1 :(得分:0)
这是在oracle,但我认为它也可以在mysql中轻松完成
SELECT year_week AS year_week,
COUNT (year_week) AS days
FROM ( SELECT TO_CHAR (timestamp, 'D') AS day_of_week,
TO_CHAR (timestamp, 'YYYY')
|| '-'
|| TO_CHAR (timestamp, 'WW')
AS year_week
FROM checkins
GROUP BY TO_CHAR (timestamp, 'YYYY')
|| '-'
|| TO_CHAR (timestamp, 'WW'),
TO_CHAR (timestamp, 'D')
ORDER BY year_week)
GROUP BY year_week order by year_week;
TO_CHAR(timestamp, 'WW') = WEEKOFYEAR
TO_CHAR(timestamp, 'D') = DAYOFWEEK
答案 2 :(得分:0)
被视为多查询问题,其中:
WEEKOFYEAR(minDate)
WEEKOFYEAR(maxDate)
解决方案看起来像这样:
SELECT DISTINCT userid, timestamp from checkins WHERE WEEKOFYEAR(timestamp) >= minDate and WEEKOFYEAR(timestamp) <= maxDate GROUP BY userid,DAYOFWEEK(timestamp);
SELECT userid, timestamp FROM result GROUP BY userid,WEEKOFYEAR(timestamp) HAVING COUNT(timestamp) >= 3 AND COUNT(timestamp) <= 5;
SELECT COUNT(*) FROM secondResult GROUP BY userid HAVING COUNT(timestamp) = (WEEKOFYEAR(maxDate) - WEEKOFYEAR(minDate));
显然,请确保在日历包装的情况下添加52。我已经验证了这个解析,并且有理由相信可以从这个解决方案中获得正确的解决方案。