如何取到每段连续日期的起始终止日期以及持续天数及起始日期距上一期终止日期的天数,能否用一句sql实现?
备注:数据库环境是sql server 2000create table tmptable(rq datetime)
go
insert tmptable values('2010.1.1')
insert tmptable values('2010.1.2')
insert tmptable values('2010.1.3')
insert tmptable values('2010.1.6')
insert tmptable values('2010.1.7')
insert tmptable values('2010.1.10')
insert tmptable values('2010.1.11')
insert tmptable values('2010.1.12')
insert tmptable values('2010.1.19')
insert tmptable values('2010.1.20')
insert tmptable values('2010.1.22')
insert tmptable values('2010.1.23')
insert tmptable values('2010.1.28')
go
---希望得到的结果
--本期起始日期 本期终止日期  持续天数 距上一期天数
--2010.1.1     2010.1.3      3        0
--2010.1.6     2010.1.7      2        3
--2010.1.10    2010.1.12     3        3
--2010.1.19    2010.1.20     2        7
--2010.1.22    2010.1.23     2        2
--2010.1.28    2010.1.28     1        5drop table tmptable
go

解决方案 »

  1.   


    CREATE TABLE #tmptable(
    rq datetime NOT NULL PRIMARY KEY CLUSTERED,
    sn int IDENTITY(1,1) NOT NULL
    )
    GO
    INSERT #tmptable VALUES('20100101')
    INSERT #tmptable VALUES('20100102')
    INSERT #tmptable VALUES('20100103')
    INSERT #tmptable VALUES('20100106')
    INSERT #tmptable VALUES('20100107')
    INSERT #tmptable VALUES('20100110')
    INSERT #tmptable VALUES('20100111')
    INSERT #tmptable VALUES('20100112')
    INSERT #tmptable VALUES('20100119')
    INSERT #tmptable VALUES('20100120')
    INSERT #tmptable VALUES('20100122')
    INSERT #tmptable VALUES('20100123')
    INSERT #tmptable VALUES('20100128')
    GO
    SELECT
    本期起始日期 = MIN(rq),
    本期终止日期 = MAX(rq),
    持续天数 = DATEDIFF(day,MIN(rq),MAX(rq))+1,
    距上一期天数 = 0,
    SN = IDENTITY(int,1,1)
    INTO #tmpresult
    FROM #tmptable
    GROUP BY rq - sn
    ORDER BY 本期起始日期
    GO
    UPDATE t SET t.距上一期天数 = DATEDIFF(day,t2.本期终止日期,t.本期起始日期)
    FROM #tmpresult t
    INNER JOIN #tmpresult t2
    ON t.SN - 1 = t2.SN
    GO
    SELECT * FROM #tmpresult ORDER BY 本期起始日期
    GO
      

  2.   


    --SQL Server 2005+
    WITH CTE AS(
    SELECT
    本期起始日期 = MIN(rq),
    本期终止日期 = MAX(rq),
    持续天数 = DATEDIFF(day,MIN(rq),MAX(rq))+1,
    SN = ROW_NUMBER() OVER(ORDER BY MIN(rq))
    FROM (
    SELECT *, sn = ROW_NUMBER() OVER(ORDER BY rq)
    FROM #tmptable
    ) tmp
    GROUP BY rq - sn
    )
    SELECT
    t.本期起始日期,
    t.本期终止日期,
    t.持续天数,
    距上一期天数 = ISNULL(DATEDIFF(day,t2.本期终止日期,t.本期起始日期),0)
    FROM CTE t
    LEFT JOIN CTE t2
    ON t.SN - 1 = t2.SN
    ORDER BY t.本期起始日期
      

  3.   


    DECLARE @tmp TABLE
        (
          id INT IDENTITY(1, 1) ,
          datatime DATETIME ,
          datanext DATETIME ,
          flag INT
        ) ;INSERT  @tmp
            ( datatime ,
              datanext ,
              flag
            )
            SELECT  a.rq AS datatime ,
                    b.rq ,
                    CASE WHEN b.rq IS NULL THEN 0
                         ELSE 1
                    END
            FROM    tmptable a
                    LEFT JOIN tmptable b ON a.rq = DATEADD(d, 1, b.rq)
            ORDER BY a.rq ;
    WITH    maco
              AS ( SELECT   ROW_NUMBER() OVER ( ORDER BY a.id DESC ) AS rowid ,
                            a.datatime AS begintime ,
                            b.datatime,DATEDIFF(d,a.datatime,b.datatime) AS num
                   FROM     @tmp a
                            LEFT JOIN @tmp b ON a.id = b.id + 1
                   WHERE    a.flag = 0
                 )
        SELECT  CONVERT(VARCHAR(10), a.begintime, 120) AS '本期起始日期' ,
                CONVERT(VARCHAR(10), ISNULL(b.datatime, a.begintime), 120) AS '本期终止日期',
                DATEDIFF(d,a.begintime,ISNULL(b.datatime, a.begintime))+1 AS '持续天数',
                ABS(ISNULL(a.num,0)) AS  '距上一期天数'
        FROM    maco a
                LEFT JOIN maco b ON a.rowid = b.rowid + 1
        ORDER BY a.begintime
        
    /*
    本期起始日期     本期终止日期     持续天数        距上一期天数
    ---------- ---------- ----------- -----------
    2010-01-01 2010-01-03 3           0
    2010-01-06 2010-01-07 2           3
    2010-01-10 2010-01-12 3           3
    2010-01-19 2010-01-20 2           7
    2010-01-22 2010-01-23 2           2
    2010-01-28 2010-01-28 1           5
    */
      

  4.   


    DECLARE @tmp TABLE
    (id INT IDENTITY(1, 1),datatime DATETIME,flag INT) ;INSERT @tmp(datatime,flag)
    SELECT  a.rq AS datatime ,
    CASE WHEN b.rq IS NULL THEN 0 ELSE 1 END
    FROM tmptable a LEFT JOIN tmptable b 
    ON a.rq = DATEADD(d, 1, b.rq) ORDER BY a.rq ;WITH  maco AS 
    (SELECT ROW_NUMBER() OVER ( ORDER BY a.id DESC ) AS rowid ,
                            a.datatime AS begintime ,
                            b.datatime,DATEDIFF(d,a.datatime,b.datatime) AS num
                   FROM     @tmp a LEFT JOIN @tmp b ON a.id = b.id + 1
                   WHERE    a.flag = 0)
        SELECT  CONVERT(VARCHAR(10), a.begintime, 120) AS '本期起始日期' ,
                CONVERT(VARCHAR(10), ISNULL(b.datatime, a.begintime), 120) AS '本期终止日期',
                DATEDIFF(d,a.begintime,ISNULL(b.datatime, a.begintime))+1 AS '持续天数',
                ABS(ISNULL(a.num,0)) AS  '距上一期天数'
        FROM    maco a LEFT JOIN maco b ON a.rowid = b.rowid + 1
        ORDER BY a.begintime
    /*
    本期起始日期     本期终止日期     持续天数        距上一期天数
    ---------- ---------- ----------- -----------
    2010-01-01 2010-01-03 3           0
    2010-01-06 2010-01-07 2           3
    2010-01-10 2010-01-12 3           3
    2010-01-19 2010-01-20 2           7
    2010-01-22 2010-01-23 2           2
    2010-01-28 2010-01-28 1           5
    */
    简单优化了一下
      

  5.   

    有没有在sql server 2000环境下用一句sql实现的方法?
      

  6.   

    数据需要判断连续,还需要计算天数,而且只有一个日期字段,关系需要行与行之间的各种比较,一句sql搞不定的
      

  7.   

    select 本期起始日期=min(rq),本期终止日期=max(rq),持续天数=max(id1)-min(id1)+1,
    距上一期天数=case a.id1-a.id2 when -1 then 0 else max(datediff(d,rq2,rq)) end 
    from (
    select id1=datediff(d,'2010-01-01',rq),id2=(select count(1) from tmptable where rq <= a.rq),rq2=(select max(rq) from tmptable where rq < a.rq),* from tmptable a
    ) a
    group by a.id1-a.id2
    /*
    本期起始日期                  本期终止日期                  持续天数        距上一期天数
    ----------------------- ----------------------- ----------- -----------
    2010-01-01 00:00:00.000 2010-01-03 00:00:00.000 3           0
    2010-01-06 00:00:00.000 2010-01-07 00:00:00.000 2           3
    2010-01-10 00:00:00.000 2010-01-12 00:00:00.000 3           3
    2010-01-19 00:00:00.000 2010-01-20 00:00:00.000 2           7
    2010-01-22 00:00:00.000 2010-01-23 00:00:00.000 2           2
    2010-01-28 00:00:00.000 2010-01-28 00:00:00.000 1           5
    警告: 聚合或其他 SET 操作消除了空值。(6 行受影响)
    */
      

  8.   

    select 本期起始日期=min(rq),本期终止日期=max(rq),持续天数=max(id1)-min(id1)+1,
        距上一期天数=case a.id1-a.id2 when -1 then 0 else max(datediff(d,rq2,rq)) end 
    from (
        select id1=datediff(d,'2010-01-01',rq),id2=(select count(1) from tmptable where rq <= a.rq),rq2=(select max(rq) from tmptable where rq < a.rq),* from tmptable a
    ) a
    group by a.id1-a.id2
      

  9.   

    研究了一下午,终于整明白10楼的SQL是如何实现我的要求了