gpt4 book ai didi

mysql - 检查连续 x 天 - 给定数据库中的时间戳

转载 作者:IT老高 更新时间:2023-10-29 00:02:45 27 4
gpt4 key购买 nike

谁能给我一个想法或提示如何在存储登录名(用户 ID、时间戳)的数据库表 (MySQL) 中检查连续 X 天?

Stackoverflow 做到了(例如,像 Enthusiast 这样的徽章 - 如果您连续登录 30 天左右...)。您必须使用哪些功能或使用方法的想法是什么?

类似于 SELECT 1 FROM login_dates WHERE ...?

最佳答案

您可以使用移位的自外连接和变量来完成此操作。请参阅此解决方案:

SELECT IF(COUNT(1) > 0, 1, 0) AS has_consec
FROM
(
SELECT *
FROM
(
SELECT IF(b.login_date IS NULL, @val:=@val+1, @val) AS consec_set
FROM tbl a
CROSS JOIN (SELECT @val:=0) var_init
LEFT JOIN tbl b ON
a.user_id = b.user_id AND
a.login_date = b.login_date + INTERVAL 1 DAY
WHERE a.user_id = 1
) a
GROUP BY a.consec_set
HAVING COUNT(1) >= 30
) a

这将返回 10,具体取决于用户是否在 任何时间 过去。

这个查询的首当其冲实际上是在第一个子选择中。让我们仔细看看,以便我们更好地理解它是如何工作的:

使用以下示例数据集:

CREATE TABLE tbl (
user_id INT,
login_date DATE
);

INSERT INTO tbl VALUES
(1, '2012-04-01'), (2, '2012-04-02'),
(1, '2012-04-25'), (2, '2012-04-03'),
(1, '2012-05-03'), (2, '2012-04-04'),
(1, '2012-05-04'), (2, '2012-05-04'),
(1, '2012-05-05'), (2, '2012-05-06'),
(1, '2012-05-06'), (2, '2012-05-08'),
(1, '2012-05-07'), (2, '2012-05-09'),
(1, '2012-05-09'), (2, '2012-05-11'),
(1, '2012-05-10'), (2, '2012-05-17'),
(1, '2012-05-11'), (2, '2012-05-18'),
(1, '2012-05-12'), (2, '2012-05-19'),
(1, '2012-05-16'), (2, '2012-05-20'),
(1, '2012-05-19'), (2, '2012-05-21'),
(1, '2012-05-20'), (2, '2012-05-22'),
(1, '2012-05-21'), (2, '2012-05-25'),
(1, '2012-05-22'), (2, '2012-05-26'),
(1, '2012-05-25'), (2, '2012-05-27'),
(2, '2012-05-28'),
(2, '2012-05-29'),
(2, '2012-05-30'),
(2, '2012-05-31'),
(2, '2012-06-01'),
(2, '2012-06-02');

这个查询:

SELECT a.*, b.*, IF(b.login_date IS NULL, @val:=@val+1, @val) AS consec_set
FROM tbl a
CROSS JOIN (SELECT @val:=0) var_init
LEFT JOIN tbl b ON
a.user_id = b.user_id AND
a.login_date = b.login_date + INTERVAL 1 DAY
WHERE a.user_id = 1

将产生:

Example Result

如您所见,我们所做的是连接表移动 +1 天。对于与前一天不连续的每一天,LEFT JOIN 都会生成一个 NULL 值。

现在我们知道不连续的日子在哪里,我们可以使用一个变量来区分每个连续的日子,方法是检测移位表的行是否是 NULL。如果它们是 NULL,则天数不是连续的,因此只需增加变量即可。如果它们是 NOT NULL,则不要增加变量:

Result With Highlighted Groupings

在我们用递增变量区分每组连续的天数之后,接下来就是按每个“组”(如 consec_set 列中所定义)分组并使用 HAVING 过滤掉少于指定连续天数(在您的示例中为 30 天)的任何集合:

Result With Grouping By The consec_set column

然后最后,我们包装THAT 查询并简单地计算连续 30 天或更长时间的集合数。如果存在一个或多个这些集合,则返回 1,否则返回 0


查看SQLFiddle step-by-step demo

关于mysql - 检查连续 x 天 - 给定数据库中的时间戳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11539065/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com