2

我正在尝试对连续的日期范围进行分组以显示每个范围的最小和最大日期。到目前为止,我使用了与此类似的解决方案: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:

结果截图

如果休息时间只是周末,有什么方法可以设置它以忽略日期范围内的休息时间?

谢谢您的帮助。

4

1 回答 1

2

已编辑

我不太喜欢我以前的想法。这是一个更好的,我认为:

  1. 根据要分组的一组日期中的第一个和最后一个日期,准备所有中间周末日期的列表。
  2. 将工作日期与周末日期一起插入,有序,因此它们都将rownum根据其正常顺序分配值。
  3. 使用您的方法查找具有以下修改的连续范围:

    1) 计算时dateRangeStart,如果是周末,则选择最近的下一个工作日;

    2) 相应地dateRangeEnd,如果是周末日期,则选择最近的前一个工作日;

    3) 为组计算日期时,只选择工作日。

  4. 从结果集中只选择那些行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;
于 2011-03-11T07:23:54.420 回答