Не совсем понятно, почему вы считаете запись 5 последовательной.SQL в вопросе подразумевает, что определение последовательного состоит в том, что ini
предыдущей записи находится на расстоянии 1 день от fin
этой записи, что является истинным.
Однако это подозрительное определение, учитывая имена этих столбцов,Я подозреваю, что вы хотите определить ind
так, чтобы он был последовательным, когда fin
этой записи находится на расстоянии 1 день от ini
следующей записи.Если это правда, то вы, вероятно, захотите сделать это:
WITH CTE AS(
-- LIST EVERY RECORD
SELECT ID, CAST(INI AS DATETIME) AS INI, CAST(FIN AS DATETIME) AS FIN,
RN = ROW_NUMBER()OVER(PARTITION BY ID ORDER BY CAST(FIN AS DATETIME) DESC)
FROM INF_LIC
WHERE PER_PRO > 201712
), CTE2 AS(
-- CALCULATE DATEDIFF
SELECT T.*,
-- DATEDIFF BETWEEN INIn - FINn-1
DD = CASE WHEN DATEDIFF(DD,T2.FIN,T.INI) IS NULL THEN 0 ELSE DATEDIFF(DD,T.INI,T2.FIN) END
FROM CTE T
-- LEFT JOIN ON EQUAL ID's AND RN = RN+1
LEFT JOIN CTE T2 ON T.RN = T2.RN - 1 AND T.ID = T2.ID
), CTE3 AS(
SELECT ID, INI, FIN, RN, ABS(DD) AS DD,
-- INDICATOR, IF -1 ITS 'SEQ', NULL MARKS THE NEWEST LOG 'FIRSTLOG' ELSE IT'S NOT SEQUENTIAL
IND = (CASE WHEN DD in (0, -1) THEN 'SEQ'
WHEN RN = 1 THEN 'FIRSTLOG'
ELSE 'NOSEQ'
END)
FROM CTE2
), CTE4 AS(
SELECT ID, INI, FIN, RN, DD, IND
FROM CTE3
GROUP BY ID, INI, FIN, RN, DD, IND
)
SELECT * FROM CTE4
ORDER BY ID, RN ASC
Где соответствующие изменения:
LEFT JOIN CTE T2 ON T.RN = T2.RN - 1 AND T.ID = T2.ID
Это объединение теперь T2.RN
минус один: вам нужно вычестьномер строки следующей записи, чтобы получить ее, а не добавить, и:
IND = (CASE WHEN DD in (0, -1) THEN 'SEQ'
WHEN RN = 1 THEN 'FIRSTLOG'
ELSE 'NOSEQ'
END)
Поскольку вы уже нумеруете строку, вы также можете использовать очевидное определение FIRSTLOG.Поскольку этот порядок соединения теперь обратен исходному предположению, DD
, равный 0, теперь означает, что это последняя запись, а не первая, поэтому он немного расширяет определение SEQ.