更新表以避免重叠日期

时间:2015-06-01 14:22:14

标签: sql-server-2008-r2 overlapping

我正在尝试编写一个查询,以便针对特定跨度重新排序日期范围。它应该做一些看起来像这样的事情

Member   Rank   Begin Date   End Date
2275     A      9/9/14       11/17/14
2275     B      9/26/14      3/24/15
2275     B      3/25/15      12/31/15
8983     A      9/16/13      3/10/15
8983     B      2/24/15      4/28/15
8983     A      4/28/15      12/31/15

让它变成

Member   Rank   Begin Date   End Date
2275     A      9/9/14       11/17/14
2275     B      11/18/14     3/24/15
2275     B      3/25/15      12/31/15
8983     A      9/16/13      3/10/15
8983     B      3/11/15      4/27/15
8983     A      4/28/15      12/31/15

为了进一步解释,我希望更新日期。除了A>之外,排名并不高。 B.并且只有A和B.等级A的日期范围应该保持不变。重叠的B排名日期还可以。我关注B排名日期与A排名日期重叠。该表非常大(约700个成员)并具有几个不同的成员ID。成员2275的第2行(等级B)将开始日期改变为11/18/15而不与第1行重叠。

我正在使用Microsoft SQL Server 2008 R2

由于

1 个答案:

答案 0 :(得分:0)

最新编辑:这是我在2012年之前所做的。我不认为这是最优雅的解决方案。

WITH a AS (
    SELECT
        1 AS lgoffset
        , NULL AS lgdefval
        , ROW_NUMBER() OVER(PARTITION BY [Member] ORDER BY [Begin Date]) AS seq
        , [Member]
        , [Rank]
        , [Begin Date]
        , [End Date]
    FROM #table 
)
SELECT
    a.seq
    , a.[Member]
    , a.[Rank]
    , a.[Begin Date]
    , CASE
        WHEN a.[Rank] = 'B' AND a.[Begin Date] <= ISNULL(aLag.[End Date], a.lgdefval)
        THEN ISNULL(aLag.[End Date], a.lgdefval)
        ELSE a.[Begin Date]
      END AS bdate2
    , a.[End Date]
INTO #b
FROM a
LEFT OUTER JOIN a aLag
    ON a.seq = aLag.seq + a.lgoffset
    AND a.[Member] = aLag.[Member]
ORDER BY [Member], [Begin Date];


UPDATE #table
SET #table.bdate = CASE
                    WHEN #table.rnk = 'B' AND #table.bdate <= (SELECT #b.bdate2 FROM #b WHERE #b.bdate2 > #b.bdate and #table.mbr = #b.mbr)
                    THEN dateadd(d, 1,(SELECT bdate2 FROM #b WHERE #b.bdate2 > #b.bdate and #table.mbr = #b.mbr )) 
                    ELSE #table.bdate
                    END  

编辑PS:以下是我之前的回答,仅适用于2012及更高版本。

您可能需要尝试以下SELECT语句,看看您是否获得了所需的结果,然后转换为UPDATE

SELECT 
[Member]
, [Rank]
, CASE
    WHEN [Rank] = 'B' AND [Begin Date] <= LAG([End Date],1,'12/31/2030') OVER(PARTITION BY [Member] ORDER BY [Begin Date]) 
    THEN DATEADD(d,1,LAG([End Date],1,'12/31/2030')OVER(PARTITION BY [Member] ORDER BY [Begin Date]))
    ELSE [Begin Date]
  END AS [Begin Date]
, [End Date]
FROM #Table
ORDER BY [Member], [Begin Date]

编辑:所以为了更新开始日期栏:

UPDATE #Table
SET [Begin Date] = (SELECT
                    CASE
                        WHEN [Rank] = 'B' AND [Begin Date] <= LAG([End Date],1,'12/31/2030') OVER(PARTITION BY [Member] ORDER BY [Begin Date]) 
                        THEN DATEADD(d,1,LAG([End Date],1,'12/31/2030')OVER(PARTITION BY [Member] ORDER BY [Begin Date]))
                        ELSE [Begin Date]
                      END AS [Begin Date]
                    FROM #Table)

编辑2:我的一些代码不正确,因为没有意识到延迟函数需要OVER语句,更新的select语句和更新语句

来源:Alternate of lead lag function in sql server 2008

http://blog.sqlauthority.com/2011/11/24/sql-server-solution-to-puzzle-simulate-lead-and-lag-without-using-sql-server-2012-analytic-function/