将SQL中的连续日期计为一个实例

时间:2016-06-06 16:51:12

标签: sql sql-server date gaps-and-islands

我想做一个日期计数,但将连续日期计为一个实例。在下面的示例表中,09/28/201309/29/2013是连续的,因此它们被视为一个实例。

user_id      date   
------       ------ 
ABC123       09/28/2013
ABC123       09/29/2013
ABC123       09/30/2013
ABC123       10/01/2013

输出:

user_id      date_count   
------       ------ 
ABC123       3

2 个答案:

答案 0 :(得分:0)

这取自Sean Lange评论。他的链接(HERE)可以满足您的需求。链接的最终代码是......

WITH
cteGroupedDates AS
( --=== Find the unique dates and assign them to a group.
 -- The group looks like a date but the date means nothing except that adjacent
 -- dates will be a part of the same group.
SELECT UniqueDate = SomeDate,
    DateGroup  = DATEADD(dd, - ROW_NUMBER() OVER (ORDER BY SomeDate), SomeDate)
FROM #MyHead
GROUP BY SomeDate
)
--===== Now, if we find the MIN and MAX date for each DateGroup, we'll have the
 -- Start and End dates of each group of contiguous daes.  While we're at it,
 -- we can also figure out how many days are in each range of days.
SELECT StartDate = MIN(UniqueDate),
    EndDate   = MAX(UniqueDate),
    Days      = DATEDIFF(dd,MIN(UniqueDate),MAX(UniqueDate))+1
FROM cteGroupedDates
GROUP BY DateGroup
ORDER BY StartDate
;

进行一些名称更改,以便更容易理解......

WITH
dateGroup AS
( --This is used to distinguish the different continuous sets of dates    
SELECT UniqueDate = date,
    DateGroup  = DATEADD(dd, - ROW_NUMBER() OVER (ORDER BY date), date)
FROM userdate
GROUP BY date
)

--Using dateGroup to get the groups of dates we can utilize it to get the count for them
SELECT StartDate = MIN(UniqueDate),
    EndDate   = MAX(UniqueDate),
    Days      = DATEDIFF(dd,MIN(UniqueDate),MAX(UniqueDate))+1,
    u.user_id
FROM dateGroup JOIN userdate u ON u.date = UniqueDate
GROUP BY DateGroup, u.user_id
ORDER BY StartDate
;

我在JOIN userdate u ON u.date = UniqueDate之后添加了FROM dateCount来获取用户ID。同时将u.user_id添加到群组中。不会工作,因为u.user_id在SELECT中(需要GROUP BY中的SELECT信息)。

表中的数据:

Data From Table

<强>证明:

Proof

----------编辑1 ----------

我将猜测你真正想要的东西!

这就是我的想法。两个不同的查询都有相同的结果。

第一次查询:

WITH
dateGroup AS
( --This is used to distinguish the different continuous sets of dates    
SELECT UniqueDate = date,
DateGroup  = DATEADD(dd, - ROW_NUMBER() OVER (ORDER BY date), date),
user_id
FROM userdate
GROUP BY date, user_id
),
userIDGroup AS
( --This is used to get the previous table that you saw in my original answer
SELECT COUNT(d.user_id) as 'Instances',
d.user_id
FROM dateGroup d
GROUP BY DateGroup, d.user_id
)

SELECT
COUNT(u.user_id) AS 'Instances',
u.user_id
FROM userIDGroup u
GROUP BY u.user_id
;

第二个查询(我更喜欢的那个):

WITH
dateGroup AS
( --This is used to distinguish the different continuous sets of dates    
SELECT UniqueDate = date,
DateGroup  = DATEADD(dd, - ROW_NUMBER() OVER (ORDER BY date), date),
user_id
FROM userdate
GROUP BY date, user_id
)

SELECT count(c.user_id) AS 'Instances', c.user_id
FROM
(
SELECT COUNT(d.user_id) as 'Instances',
d.user_id
FROM dateGroup d
GROUP BY DateGroup, d.user_id
) c GROUP BY c.user_id
;

<强>证明:

enter image description here

答案 1 :(得分:0)

调用您的源表users_and_dates,下面将删除第二天也在数据集中的任何日期。

select t1.user_id, 
    count(*)
from users_and_dates t1
join users_and_dates t2
    on t1.user_id=t2.user_id
        and t1.date+1=t2.date
where t2.user_id is null