나는 과거에도 비슷한 문제가 있었고 범위가 연속적이어야하는 경우 최상의 방법은 범위의 종료 날짜를 없애고 다음 시작 날짜로 계산하는 것입니다. 그런 요구는 다음과 같이 뷰를 생성 할 경우 :
SELECT FromDate,
( SELECT DATEADD(DAY, -1, MIN(DateFrom))
FROM YourTable b
WHERE b.FromDate > a.FromDate
) [ToDate],
Value
FROM YourTable a
이 결코 크로스, 그러나 반드시 어떤 일을 보장하지 않습니다 수 2 개 범위는 원하는 결과를 얻기 위해 삽입에 필요하다는 것을 보장하지만, 더 유지 관리해야하며, 오류의 범위가 시작일과 종료일 모두를 저장하는 것보다 적습니다.
나는 아래 내가 멀리 DateTo
필드에 할 일이 많이 유지 보수성이 향상되지 않습니다 실현을 모두 기입 한 후 칙
, 그것은 여전히 검증을위한 코드의 상당한 양이 필요하지만 어쨌든 나는 그것을 어떻게 할 것인가.
DECLARE @T table (DateFrom DATE, Value INT)
INSERT INTO @T VALUES ('20120101', 10), ('20120202', 15), ('20120207', 12), ('20120211', 15)
DECLARE @NewFrom DATE = '20120209',
@NewTo DATE = '20120210',
@NewValue INT = 8
-- SHOW INITIAL VALUES FOR DEMONSTATIVE PURPOSES --
SELECT DateFrom,
ISNULL(( SELECT DATEADD(DAY, -1, MIN(DateFrom))
FROM @t b
WHERE b.DateFrom > a.DateFrom
), CAST(GETDATE() AS DATE)) [DateTo],
Value
FROM @t a
ORDER BY DateFrom
;WITH CTE AS
( SELECT DateFrom,
( SELECT DATEADD(DAY, -1, MIN(DateFrom))
FROM @t b
WHERE b.DateFrom > a.DateFrom
) [DateTo],
Value
FROM @t a
),
MergeCTE AS
( SELECT @NewFrom [DateFrom], @NewValue [Value], 'INSERT' [RowAction]
WHERE @NewFrom < @NewTo -- ENSURE A VALID RANGE IS ENTERED
UNION ALL
-- INSERT A ROW WHERE THE NEW DATE TO SLICES AN EXISTING PERIOD
SELECT DATEADD(DAY, 1, @NewTo), Value, 'INSERT'
FROM CTE
WHERE @NewTo BETWEEN DateFrom AND DateTo
UNION ALL
-- DELETE ALL ENTRIES STARTING WITHIN THE DEFINED PERIOD
SELECT DateFrom, Value, 'DELETE'
FROM CTE
WHERE DateFrom BETWEEN @NewFrom AND @NewTo
)
MERGE INTO @t t USING MergeCTE c ON t.DateFrom = c.DateFrom AND t.Value = c.Value
WHEN MATCHED AND RowAction = 'DELETE' THEN DELETE
WHEN NOT MATCHED THEN INSERT VALUES (c.DateFrom, c.Value);
SELECT DateFrom,
ISNULL(( SELECT DATEADD(DAY, -1, MIN(DateFrom))
FROM @t b
WHERE b.DateFrom > a.DateFrom
), CAST(GETDATE() AS DATE)) [DateTo],
Value
FROM @t a
ORDER BY DateFrom
나는 논리를 이해하지 못했습니다. 좀 더 구체적으로 해주실 수 있습니까? – Diego
여기서 고려해야 할 많은 경우가 있다고 생각합니다. 새 행이 From/To를 기존 행과 완전히 같게 할 수 있고 완전히 바꿀 수 있습니까? 여러 행을 완전히 커버한다면? 나는 그것이 기존의 두 범위에 걸쳐있을 수 있다고 가정합니까? –
날짜 범위는 시간 순서를 나타내야하며, 두 범위는 서로 확장 될 수 없습니다. – AngeloBad