【问题标题】:Min effective and termdate for contiguous dates连续日期的最小有效日期和期限日期
【发布时间】:2009-05-12 05:56:40
【问题描述】:

有没有办法使用 SQL 2000 查询来实现以下操作,我到处找,但找不到任何工作的 sn-p。

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

如果不可能使用不同的查询获得连续段的最小生效日期和最大期限日期也对我有用。

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

【问题讨论】:

  • 注意。您的 effdate 格式为 YYYY-DD-MM,而您的 termdate 格式为 YYYY-MM-DD。我以为我有一个更优雅的解决方案,直到我意识到情况确实如此。您可能需要澄清这一点。
  • 嗨, effdate 和 termdate 的格式都相同 YYYY-MM-DD。如果您能分享您的解决方案,那就太好了。

标签: sql sql-server


【解决方案1】:

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

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   

【讨论】:

    【解决方案2】:

    不幸的是,您可能不得不使用光标。这样的事情应该可以工作。

    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
    

    【讨论】:

    • 抱歉,我没有查看使用游标
    【解决方案3】:

    从 tab1 中选择 min(effdate),max(termdate) 其中年份(effdate)= 年份(termdate) 按年份分组(有效期) 按 min(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

    【讨论】:

    • 如果 effdate 和 termdate 在不同的年份,这会起作用吗
    【解决方案4】:

    如果不使用临时表,我认为这是不可能的。 (您不排除它们的使用,但在 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
    

    【讨论】:

      猜你喜欢
      • 2020-08-10
      • 1970-01-01
      • 2021-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多