Вы можете использовать следующий запрос:
;WITH CTE AS (
SELECT Row, Rank, BeginDate, EndDate,
ROW_NUMBER() OVER (ORDER BY BeginDate) AS rn
FROM mytable
), ToUpdate AS (
SELECT c1.Row, c1.Rank, c1.BeginDate, c1.EndDate,
c2.Rank AS pRank, c2.EndDate AS pEndDate,
c3.Rank AS nRank, c3.BeginDate AS nBeginDate
FROM CTE AS c1
LEFT JOIN CTE AS c2 ON c1.rn = c2.rn + 1
LEFT JOIN CTE AS c3 ON c1.rn = c3.rn - 1
WHERE c1.Rank = 'B'
)
UPDATE ToUpdate
SET BeginDate = CASE
WHEN pEndDate IS NULL
THEN BeginDate
WHEN (pEndDate >= BeginDate) AND (pRank = 'A')
THEN DATEADD(d, 1, pEndDate)
ELSE BeginDate
END,
EndDate = CASE
WHEN nBeginDate IS NULL
THEN EndDate
WHEN (nBeginDate <= EndDate) AND (nRank = 'A')
THEN DATEADD(d, -1, nBeginDate)
ELSE EndDate
END
CTE
изначально построен для назначения последовательного, восходящий номера для каждой записи Вашего стола. ROW_NUMBER()
Функция окна используется для этой цели.
В качестве основы мы строим ToUpdate
. Этот последний CTE
содержит значения даты текущие, а также предыдущие и следующий записей. Это LEFT JOIN
:
LEFT JOIN CTE AS c2 ON c1.rn = c2.rn + 1
используется для соединения вместе с предыдущей записи, в то время как этот:
LEFT JOIN CTE AS c3 ON c1.rn = c3.rn - 1
используется для соединения вместе с следующей записи.
Используя выражения CASE
, мы теперь можем легко идентифицировать перекрытия и, если они есть, выполнить обновление.
Demo here
ли вы имеете в виду вы используете SQL Server? Пожалуйста, пометьте свой вопрос с помощью РСУБД. Кроме того, вы просто ищете помощь в слиянии дат или больше вопросов? Нужно ли понимать ваш рейтинг? –
Да, я использую SQL Server 2008 R2. Я хочу обновить даты. И нет, нет никакого рейтинга в рейтинге, кроме A> B. И есть только A и B. Диапазоны дат с рангом A должны оставаться нетронутыми. – enigmaface
Что делать, если у вас есть два последовательных '' B'' ранжированных отчета с перекрывающимися датами? –