最小有效期和连续日期的期限

时间:2009-05-12 05:56:40

标签: sql sql-server

使用SQL 2000查询是否有办法实现以下目标,我到处寻找,但找不到任何工作片段。

我有连续的日期段,要求是获取每个连续日期的最小生效日期和最长生效日期。

如果无法获得最小有效日期,并且使用不同查询的连续段的最大termdate也适用于我。

ID  effdate     termdate
1   2007-05-01  2007-05-31
2   2007-06-01  2007-06-30
3   2007-07-01  2007-09-30
4   2008-03-01  2008-03-31
5   2008-05-01  2008-05-31
6   2008-06-01  2008-06-30

预期结果:

2007-05-01  2007-09-30
2008-03-01  2008-03-31
2008-05-01  2008-06-30

4 个答案:

答案 0 :(得分:2)

我做了类似这样的事情来获得期限和期限相同,将它们作为两个单独的视图并获得最终结果。

SELECT distinct e0.effdate,e0.ID
  FROM  dbo.datatable e0    LEFT OUTER JOIN dbo.datatable PREV ON       
       PREV.ID = e0.ID 
 AND  PREV.termdate = DATEADD(dy, -1, e0.Effdate)        
  WHERE PREV.ID IS NULL   

答案 1 :(得分:0)

不幸的是,您可能不得不使用游标。这样的事情应该有效。

DECLARE @Results TABLE
(
    effdate DATETIME,
    termdate DATETIME
)

DECLARE @Date1 DATETIME, 
        @Date2 DATETIME,
        @StartDate DATETIME, 
        @EndDate DATETIME

DECLARE @Cursor CURSOR 

SET @Cursor = CURSOR FAST_FORWARD
FOR
SELECT effdate, termdate FROM <TABLE>

OPEN @Cursor
FETCH NEXT FROM @Cursor
INTO @Date1,@Date2

WHILE @@FETCH_STATUS = 0
BEGIN
    IF @StartDate IS NULL
    BEGIN
        SELECT  @StartDate = @Date1,
                @EndDate = @Date2
    END
    ELSE
    BEGIN
        IF DateDiff(d,@EndDate,@Date1) = 1
        BEGIN
            SET @EndDate = @Date2
        END
        ELSE
        BEGIN
            INSERT INTO @Results
            SELECT @StartDate, @EndDate

            SELECT  @StartDate = @Date1,
                    @EndDate = @Date2
        END
    END


    FETCH NEXT FROM @Cursor
    INTO @Date1,@Date2
END

INSERT INTO @Results
SELECT @StartDate, @EndDate

CLOSE @Cursor
DEALLOCATE @Cursor 

SELECT * FROM @Results

答案 2 :(得分:0)

从tab1中选择min(effdate),max(termdate) 年(effdate)=年(termdate) 逐年分组(effdate) 按分钟排序(effdate)

结果

2007-05-01 00:00:00.000 2007-09-30 00:00:00.000

2008-03-01 00:00:00.000 2008-06-30 00:00:00.000

答案 3 :(得分:0)

如果不使用临时表,我认为这是不可能的。 (你不排除它们的使用,但是在Mike Bennett发布他的答案之前你没有排除使用游标)

我有理由相信这是一个通用的解决方案 - 它使用了一个未记录的功能,在更新语句中可以多次更改变量的值。

如果您的表中的记录按照effdate的顺序输入,您可以跳过创建人工身份列以保证订单(我的查询中的autoID)。

-- Setup test data

IF object_id('tempdb..#test1') IS NOT NULL
        DROP TABLE #test1
GO

CREATE TABLE #test1
(id INT
,effdate DATETIME
,termdate DATETIME
)

INSERT #test1
      SELECT 1,'2007-05-01','2007-05-31'
UNION SELECT 2 ,'2007-06-01','2007-06-30'
UNION SELECT 3 ,'2007-07-01','2007-09-30'
UNION SELECT 4 ,'2008-03-01','2008-03-31'
UNION SELECT 5 ,'2008-05-01','2008-05-31'
UNION SELECT 6 ,'2008-06-01','2008-06-30'
GO

IF object_id('tempdb..#t') IS NOT NULL
        DROP TABLE #t

GO

-- Order the records by effdate
SELECT IDENTITY(INT,1,1) AS autoId
,cast(NULL AS INT) groupID
,*
INTO #t
FROM #test1
ORDER BY effdate

UPDATE #t
SET groupID = 1
WHERE autoID = 1

DECLARE @gp INT
SET @gp = 1

--update groupID using the undocumented variable-update method
UPDATE t2
SET @gp = CASE WHEN t1.termdate = t2.effdate - 1
               THEN @gp 
               ELSE @gp + 1
          END
,groupID = @gp
FROM #t AS t1
JOIN #t AS t2
ON t1.autoID = t2.autoID - 1

--output results
select min(effdate), max(termdate)
from #t
group by groupID
order by groupID