我有这样的数据
Month CalendarDate
1 02/01/2014 00:00
1 03/01/2014 00:00
1 04/01/2014 00:00
1 05/01/2014 00:00
1 06/01/2014 00:00
1 07/01/2014 00:00
1 08/01/2014 00:00
1 15/01/2014 00:00
1 16/01/2014 00:00
1 17/01/2014 00:00
1 18/01/2014 00:00
1 26/01/2014 00:00
1 27/01/2014 00:00
1 28/01/2014 00:00
1 29/01/2014 00:00
2 04/02/2014 00:00
2 05/02/2014 00:00
2 06/02/2014 00:00
2 07/02/2014 00:00
2 08/02/2014 00:00
2 09/02/2014 00:00
2 10/02/2014 00:00
需要查找一个月中连续日期的日期组,例如1月份的3个组,即2到8,15到18和26到29 如同在月份中只有一组从04到10
答案 0 :(得分:0)
我构建了下面的架构,并添加了几个日期以确保我得到了边缘案例。这将更改结果,以便每月再添加一个分组:
CREATE TABLE EVENTS (CalendarDate DATETIME);
INSERT INTO EVENTS VALUES ('01/02/2014 00:00');
INSERT INTO EVENTS VALUES ('01/03/2014 00:00');
INSERT INTO EVENTS VALUES ('01/04/2014 00:00');
INSERT INTO EVENTS VALUES ('01/05/2014 00:00');
INSERT INTO EVENTS VALUES ('01/06/2014 00:00');
INSERT INTO EVENTS VALUES ('01/07/2014 00:00');
INSERT INTO EVENTS VALUES ('01/08/2014 00:00');
INSERT INTO EVENTS VALUES ('01/15/2014 00:00');
INSERT INTO EVENTS VALUES ('01/16/2014 00:00');
INSERT INTO EVENTS VALUES ('01/17/2014 00:00');
INSERT INTO EVENTS VALUES ('01/18/2014 00:00');
INSERT INTO EVENTS VALUES ('01/26/2014 00:00');
INSERT INTO EVENTS VALUES ('01/27/2014 00:00');
INSERT INTO EVENTS VALUES ('01/28/2014 00:00');
INSERT INTO EVENTS VALUES ('01/29/2014 00:00');
INSERT INTO EVENTS VALUES ('01/31/2014 00:00');
INSERT INTO EVENTS VALUES ('02/01/2014 00:00');
INSERT INTO EVENTS VALUES ('02/04/2014 00:00');
INSERT INTO EVENTS VALUES ('02/05/2014 00:00');
INSERT INTO EVENTS VALUES ('02/06/2014 00:00');
INSERT INTO EVENTS VALUES ('02/07/2014 00:00');
INSERT INTO EVENTS VALUES ('02/08/2014 00:00');
INSERT INTO EVENTS VALUES ('02/09/2014 00:00');
INSERT INTO EVENTS VALUES ('02/10/2014 00:00');
然后我从变量姿态接近它,使第二个查询中的子选择更短,并且在现实世界中,减少真实的更大表上的扫描次数。
DECLARE @DateGroup TABLE (CalendarDate DATE, GroupID VARCHAR(40));
INSERT INTO @DateGroup
SELECT CalendarDate
, CASE
WHEN EXISTS (SELECT 1 FROM EVENTS E2 WHERE MONTH(E2.CalendarDate) = MONTH(E.CalendarDate) AND DATEDIFF(dd,E.CalendarDate,E2.CalendarDate) = -1) THEN 'Group'
ELSE CAST(NEWID() AS VARCHAR(40))
END AS GroupID
FROM EVENTS E
SELECT RIGHT(CONVERT(VARCHAR,CalendarDate,113),8) AS MonthOfDate, COUNT(DISTINCT GroupID) AS Groups
FROM (
SELECT CalendarDate, CASE GroupID WHEN 'Group' THEN (SELECT TOP 1 GroupID FROM @DateGroup E WHERE E.CalendarDate < D.CalendarDate AND GroupID != 'Group' ORDER BY CalendarDate DESC) ELSE GroupID END AS GroupID
FROM @DateGroup D
) Z
GROUP BY RIGHT(CONVERT(VARCHAR,CalendarDate,113),8)
ORDER BY MIN(CalendarDate)
这给了我以下结果:
MonthOfDate Groups
Jan 2014 4
Feb 2014 2
答案 1 :(得分:0)
;with cte(Month, Year, Sequence) as
(
select d.Month,
datepart(yy,d.CalendarDate),
DATEPART(d, d.CalendarDate) - row_number() over(partition by Month order by Month, CalendarDate) Sequence
from Dates d
group by d.Month, d.CalendarDate
)
select Month, Year, COUNT(Sequence) Groups
from(
select c.Month, c.Year, COUNT(sequence) Sequence
from cte c
group by c.Month, c.Year, c.Sequence
having COUNT(Sequence) > 2
) x
group by Month, Year
此行计算将在顺序运行中为每个记录重复的值
DATEPART(d, d.CalendarDate) - row_number() over(partition by Month order by Month, CalendarDate)
然后,这只是对结果进行分组的问题。此查询将连续三个月视为一个组。如果你想连续两个月,那么改变这一行
having COUNT(Sequence) > 2
到
having COUNT(Sequence) > 1