SQL查询:连续30天每天访问该站点

时间:2010-11-28 17:56:54

标签: sql sql-server-2008

在堆栈溢出中,有一个名为“Enthusiast”的徽章,可以通过“每天连续30天访问该网站”获得

如何在sql server中编写此查询?

7 个答案:

答案 0 :(得分:5)

使用

创建表格
Id, LastVisit, DaysConsecutivelyVisited

并在每次访问时恰当地更新表格。逻辑很清楚,并且不需要丑陋的SQL查询来提取所需的信息。

答案 1 :(得分:2)

您可以通过阅读meta.stackoverflow.com上标记为发烧友徽章的问题来了解这些挑战。

一个重要问题是对网站构成“访问”的内容。我们中的许多人一次只能登录几天。所以他们不计算登录。他们对访问的内容有一个特殊的定义。您必须定义访问的内容。

混淆的根源是日期的定义。我相信SO正在使用GMT,这意味着日期在许多用户的本地日期中间发生变化。如果您有其他时区的用户,则必须指定您日期所用的时区。

如果您有幸能够根据登录信息计算,并且您的用户位于同一时区,那么您的记录保存相对容易。您只需记录每次登录,然后按照Jeremiah Peschka的建议使用SQL来寻找差距。

如果您必须跟踪访问,而不是登录,则必须定义访问内容,并创建单独的数据库表以记录访问。显然,会有很多日志记录到该表,您可能希望考虑所有这些数据库调用的性能损失与获取此信息的值

答案 2 :(得分:0)

只要您有一列用于跟踪用户访问过网站的原始日期,您就可以编写查询以查找gaps in the data。在这里放置一个特定的查询是相当冗长的(毫无疑问,比我聪明的人会想出一个证明我错误的简短例子),但这很可能,只需要花费一点时间来编写代码来检测。 / p>

答案 3 :(得分:0)

你可以简单地拥有一个跟踪登录的表,以及自上次登录以来的天数(字面上只有: userid,logindate,dayssincelastlogin )。这意味着您需要做的就是查询该表,确保自上次登录以来的天数在过去30天内小于或等于1。

答案 4 :(得分:0)

假设您有桌面访问(uid,时间戳),我会采取慷慨的路线,并说如果任何最近的一对访问间隔超过48小时,该人不可能每天访问。另外,我会假设他们做了(事实上,他们可以在一个晚上和两个早晨之后或其他什么,但无论如何,可以调整)。你可以很容易地使用day的其他定义,因为这只返回两点之间的最大距离。

Jeremiah的链接可能对大型数据集更有效,但更简单的查询是:

SELECT uid, MAX(dist) FROM
    (SELECT v1.uid AS uid, MIN(v1.timestamp-v2.timestamp) AS dist
        FROM visits v1 LEFT JOIN visits v2
        ON v1.uid = v2.uid
        WHERE $dateRangeLimiter
        GROUP BY v1.uid, v1.timestamp) WHERE uid = $targetUid

这将获得给定WHERE子句和UID规范中两个时间点之间的最大距离。如果您只是在寻找一个uid,那么WHERE应该被推入内部SELECT;就目前而言,查询将为所有用户执行此操作。

这不是最有效的方式,但如果这就是你所拥有的,并且它不是那么大的数据集,它应该可以正常工作。

答案 5 :(得分:0)

让我们假设您已经有一个表{1} logindays (user, day),每个用户和每天访问一行(通过舍入登录时间和分组来完成此操作)。 DOK已经解释了“日”定义的问题。

这里是:

select user, min(day) enthusiast_since from
( select user, day, lag(day, 29) over (partition by user order by day) daydiff from logindays )
where day - daydiff = 29
group by user;

(29因为第1天是第30天之前的29天)

答案 6 :(得分:0)

最准确的方法是记录用户的活动。通过这种方式,对于那些通过非活动状态保持登录数天(不应该计算在内)的人来说,“他是否已登录”并不存在混淆。

对于维护,删除所有日志记录> 30天。

查询表格,了解过去30天内任何给定用户的任意两个日志条目之间的最长时间距离。如果最大结果是< = 1,他就赢了。

我相信你可以弄清楚如何编写查询。