查找给定时间间隔内的记录数
Finding count of records in given interval
我有一个 table 用户登录,我想找到在 5 天内登录网站超过 3 次的用户。
例如我的table是:
id | user_id | login_date
---+---------+--------------
1 | 10 | 10.1.2014 00:00
2 | 10 | 11.1.2014 10:10
3 | 12 | 11.1.2014 11:00
4 | 10 | 11.1.2014 12:00
5 | 12 | 12.1.2014 00:00
6 | 10 | 13.1.2014 10:00
7 | 12 | 18.1.2014 00:00
8 | 12 | 22.1.2014 09:00
对于此示例 table,我想选择 user_id 10,因为 he/she 在 5 天内登录了 3 次以上。
你能帮我一下吗?
编辑:我忘了说数据库是 sql server 2008
如果您使用的是 SQL Server 2012+,那么您可以使用 LEAD
window 函数来计算任意 3 个连续记录之间的天数差异:
select distinct USER_ID
from (
select USER_ID,
datediff(d, login_date,
LEAD(login_date, 2) OVER (PARTITION BY user_id
ORDER BY login_date)) as diffDates
from users ) t
where t.diffDates <= 5
然后简单地 select 天数差等于或小于 5 的那些 USER_IDs
。
如果您使用的是 SQL Server 2008 或 2005,则可以将 ROW_NUMBER
与自联接结合使用以模拟 LEAD
功能:
;WITH CTE AS (
SELECT id, user_id, login_date,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date) AS rn
FROM users
)
SELECT DISTINCT user_id
FROM (
SELECT c1.user_id,
DATEDIFF(d, c1.login_date, c2.login_date) AS diffInDays
FROM CTE AS c1
INNER JOIN CTE AS c2 ON c1.user_id = c2.user_id AND c1.rn = c2.rn - 2
) t
WHERE t.diffInDays <= 5
上述查询中的 diffInDays
本质上是任意 3 次连续用户登录之间的天数滚动差异。
您可以使用以下查询来获取结果。
如您所见,您可以使用 DATEADD
函数来计算参考日期,并使用必须过滤的登录计数大于或等于 3
Select count(*),user_id
from table_name
where login_date>=DATEADD (day,-5,GETDATE())
group by user_id
having COUNT(*) >=3
您可以通过在 user_id
上自行加入 table 来做到这一点,其中 JOIN
获取其加入记录后 5 天内的记录,如下所示:
CREATE TABLE #login
(
id INT ,
user_id INT ,
login_date DATETIME
)
INSERT INTO #login
( id, user_id, login_date )
VALUES ( 1, 10, '2014-01-10 00:00' ),
( 2, 10, '2014-01-11 10:10' ),
( 3, 12, '2014-01-11 11:00' ),
( 4, 10, '2014-01-11 12:00' ),
( 5, 12, '2014-01-12 00:00' ),
( 6, 10, '2014-01-13 10:00' ),
( 7, 12, '2014-01-18 00:00' ),
( 8, 12, '2014-01-22 09:00' )
SELECT t1.user_id ,
t1.login_date AS FirstDateInLoginPeriod ,
COUNT(t2.user_id) AS LoginCount
FROM #login t1
INNER JOIN #login t2 ON t2.user_id = t1.user_id
AND t2.login_date
BETWEEN t1.login_date AND DATEADD(DAY, 5, t1.login_date)
GROUP BY t1.user_id ,
t1.login_date
HAVING COUNT(t2.user_id) > 3
DROP TABLE #login
生产:
user_id FirstDateInLoginPeriod LoginCount
----------------------------------------------
10 2014-01-10 00:00:00.000 4
我有一个 table 用户登录,我想找到在 5 天内登录网站超过 3 次的用户。
例如我的table是:
id | user_id | login_date
---+---------+--------------
1 | 10 | 10.1.2014 00:00
2 | 10 | 11.1.2014 10:10
3 | 12 | 11.1.2014 11:00
4 | 10 | 11.1.2014 12:00
5 | 12 | 12.1.2014 00:00
6 | 10 | 13.1.2014 10:00
7 | 12 | 18.1.2014 00:00
8 | 12 | 22.1.2014 09:00
对于此示例 table,我想选择 user_id 10,因为 he/she 在 5 天内登录了 3 次以上。
你能帮我一下吗?
编辑:我忘了说数据库是 sql server 2008
如果您使用的是 SQL Server 2012+,那么您可以使用 LEAD
window 函数来计算任意 3 个连续记录之间的天数差异:
select distinct USER_ID
from (
select USER_ID,
datediff(d, login_date,
LEAD(login_date, 2) OVER (PARTITION BY user_id
ORDER BY login_date)) as diffDates
from users ) t
where t.diffDates <= 5
然后简单地 select 天数差等于或小于 5 的那些 USER_IDs
。
如果您使用的是 SQL Server 2008 或 2005,则可以将 ROW_NUMBER
与自联接结合使用以模拟 LEAD
功能:
;WITH CTE AS (
SELECT id, user_id, login_date,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date) AS rn
FROM users
)
SELECT DISTINCT user_id
FROM (
SELECT c1.user_id,
DATEDIFF(d, c1.login_date, c2.login_date) AS diffInDays
FROM CTE AS c1
INNER JOIN CTE AS c2 ON c1.user_id = c2.user_id AND c1.rn = c2.rn - 2
) t
WHERE t.diffInDays <= 5
上述查询中的 diffInDays
本质上是任意 3 次连续用户登录之间的天数滚动差异。
您可以使用以下查询来获取结果。
如您所见,您可以使用 DATEADD
函数来计算参考日期,并使用必须过滤的登录计数大于或等于 3
Select count(*),user_id
from table_name
where login_date>=DATEADD (day,-5,GETDATE())
group by user_id
having COUNT(*) >=3
您可以通过在 user_id
上自行加入 table 来做到这一点,其中 JOIN
获取其加入记录后 5 天内的记录,如下所示:
CREATE TABLE #login
(
id INT ,
user_id INT ,
login_date DATETIME
)
INSERT INTO #login
( id, user_id, login_date )
VALUES ( 1, 10, '2014-01-10 00:00' ),
( 2, 10, '2014-01-11 10:10' ),
( 3, 12, '2014-01-11 11:00' ),
( 4, 10, '2014-01-11 12:00' ),
( 5, 12, '2014-01-12 00:00' ),
( 6, 10, '2014-01-13 10:00' ),
( 7, 12, '2014-01-18 00:00' ),
( 8, 12, '2014-01-22 09:00' )
SELECT t1.user_id ,
t1.login_date AS FirstDateInLoginPeriod ,
COUNT(t2.user_id) AS LoginCount
FROM #login t1
INNER JOIN #login t2 ON t2.user_id = t1.user_id
AND t2.login_date
BETWEEN t1.login_date AND DATEADD(DAY, 5, t1.login_date)
GROUP BY t1.user_id ,
t1.login_date
HAVING COUNT(t2.user_id) > 3
DROP TABLE #login
生产:
user_id FirstDateInLoginPeriod LoginCount
----------------------------------------------
10 2014-01-10 00:00:00.000 4