我正在尝试对连续的日期范围进行分组,以显示每个范围的最小和最大日期。到目前为止,我已经使用了类似于这个的解决方案:http://www.sqlservercentral.com/articles/T-SQL/71550/但是我在SQL 2000上,所以我不得不做一些更改。到目前为止,这是我的程序:
create table #tmp
(
date smalldatetime,
rownum int identity
)
insert into #tmp
select distinct date from testDates order by date
select
min(date) as dateRangeStart,
max(date) as dateRangeEnd,
count(*) as dates,
dateadd(dd,-1*rownum, date) as GroupID
from #tmp
group by dateadd(dd,-1*rownum, date)
drop table #tmp
除了一个问题外,它正是我想要的:周末。我的数据集没有周末日期的记录,这意味着找到的任何组最多都是5天。例如,在下面的结果中,我希望最后3组显示为单个记录,dateRangeStart为10/6,dateRangeEnd为10/20:
我是否有某种方法可以将此设置为忽略日期范围内的休息时间,如果该休息只是一个周末?
感谢您的帮助。
答案 0 :(得分:2)
<强> EDITED 强>
我不太喜欢我以前的想法。我认为这是一个更好的一个:
rownum
个值。使用您的方法查找连续范围,并进行以下修改:
1)在计算dateRangeStart
时,如果是周末日期,则选择最接近的工作日;
2)相应地dateRangeEnd
,如果是周末日期,则选择最近的工作日;
3)在计算小组的日期时,只选择工作日。
从结果集中选择仅dates > 0
的行,从而消除仅由周末组成的组。
这是该方法的一个实现,假设一周从星期日开始(DATEPART
返回1
),周末天是星期日和星期六:
DECLARE @tmp TABLE (date smalldatetime, rownum int IDENTITY);
DECLARE @weekends TABLE (date smalldatetime);
DECLARE @minDate smalldatetime, @maxDate smalldatetime, @date smalldatetime;
/* #1 */
SELECT @minDate = MIN(date), @maxDate = MAX(date)
FROM testDates;
SET @date = @minDate - DATEPART(dw, @minDate) + 7;
WHILE @date < @maxDate BEGIN
INSERT INTO @weekends
SELECT @date UNION ALL
SELECT @date + 1;
SET @date = @date + 7;
END;
/* #2 */
INSERT INTO @tmp
SELECT date FROM testDates
UNION
SELECT date FROM @weekends
ORDER BY date;
/* #3 & #4 */
SELECT *
FROM (
SELECT
MIN(date + CASE DATEPART(dw, date) WHEN 1 THEN 1 WHEN 7 THEN 2 ELSE 0 END)
AS dateRangeStart,
MAX(date - CASE DATEPART(dw, date) WHEN 1 THEN 2 WHEN 7 THEN 1 ELSE 0 END)
AS dateRangeEnd,
COUNT(CASE WHEN DATEPART(dw, date) NOT IN (1, 7) THEN date END) AS dates,
DATEADD(d, -rownum, date) AS GroupID
FROM @tmp
GROUP BY DATEADD(d, -rownum, date)
) s
WHERE dates > 0;