我有一个事件记录数据库,我需要找到每个客户的所有事件,并在每个客户的最后一个记录到第一个记录的一周间隔内对它们进行分组。
FirstEvent LastEvent Client
==
2011-01-01 06:55:21.000 |2011-04-30 21:46:09.000 |Client1
2011-01-01 06:20:00.000 |2011-02-23 12:43:55.000 |Client2
2011-01-03 08:34:33.000 |2011-04-30 09:00:39.000 |Client3
2011-01-01 02:14:45.000 |2011-04-30 15:31:41.000 |Client4
2011-01-01 08:08:12.000 |2011-02-21 09:41:28.000 |Client5
2011-02-01 11:29:28.000 |2011-04-29 09:13:25.000 |Client6
现在我必须计算每个客户的记录并将它们分组为
Client From To Records
==
Client1 |2011-04-30 21:46:09.000 |2011-04-23 21:46:09.000 |200
Client1 |2011-04-16 21:46:09.000 |2011-04-09 21:46:09.000 |400
...Until the the first date
Client1 |2011-01-08 06:55:21.000 |2011-01-01 06:55:21.000 |250
Client2 |2011-02-23 12:43:55.000 |2011-02-16 12:43:55.000 |50
...The same for each user
我希望有人可以帮我找到输出方法。
答案 0 :(得分:2)
您可以使用DATEDIFF功能按周分组。
SELECT e.[Client]
, [From] = MIN(e.EventDate)
, [To] = MAX(e.EventDate)
, [Records] = COUNT(*)
FROM Events AS e
GROUP BY e.[Client]
, DATEDIFF(week, '1900-01-01', e.EventDate)
答案 1 :(得分:1)
好的,我认为这完全符合您的要求:
SELECT CONVERT(datetime, '2011-01-01 06:55:21.000', 120) AS event, 'client1' AS Client
INTO #EVENTS
UNION ALL SELECT '2011-01-08 06:55:20.000', 'client1'
UNION ALL SELECT '2011-04-30 21:46:09.000', 'client1'
;WITH E AS (
SELECT
Client,
MIN(event) AS FirstEvent
FROM #EVENTS
GROUP BY Client
)
,B AS (
SELECT
E.Client,
E.FirstEvent,
COUNT(*) AS Records,
DATEDIFF(DAY, 0, c.event - E.FirstEvent) / 7 AS [weeks]
FROM #EVENTS c
JOIN E ON E.Client = c.Client
GROUP BY E.Client, E.FirstEvent, DATEDIFF(DAY, 0, c.event - E.FirstEvent) / 7
)
SELECT
Client,
DATEADD(WEEK, weeks, FirstEvent) AS [From],
DATEADD(WEEK, weeks + 1, FirstEvent) AS [To],
Records
FROM B
ORDER BY Client, weeks;
DROP TABLE #EVENTS
但是,如果某一周没有记录,它将省略该行而不是返回包含记录值0的行:
修改强>
如果您想知道我为DAY
使用WEEK
代替DATEDIFF
的原因,那就是避免周日或周一是一周的第一天出现问题。
答案 2 :(得分:0)
如果开始和结束之间的周数小于2048,这应该有效,如果没有,那么我会建议使用数字表。
SELECT
client
,DATEADD(WK,(number * -1) -1,fromdate) as [from]
,DATEADD(WK,number * -1,fromdate) as [to]
,COUNT(client) as records
from #sample
LEFT OUTER JOIN (SELECT number FROM dbo.spt_values WHERE type = 'p') nums
on nums.number <= DATEDIFF(WK,todate,fromdate)
GROUP BY client
,DATEADD(WK,(number * -1) -1,fromdate)
,DATEADD(WK,number * -1,fromdate)
ORDER BY
client
,DATEADD(WK,(number * -1) -1,fromdate) DESC