Мне нужно знать, сколько времени (дней) было зарегистрировано пользователями и промежутки между незарегистрированным временем.В этой таблице я просто храню идентификатор и их начальную и конечную дату (ID, INI, FIN, соответственно).Мне уже удалось обнаружить пропуски в трех записях на основе условных выражений, сгруппировав пользователей с номером строки, а затем сравнить новейший журнал со следующим и т. Д.
Проблема в том, что у меня есть люди с n журналами исторически иЯ не могу написать n левых соединений и n условных выражений.Я пытаюсь сделать мой текущий код более масштабируемым, обнаруживая эти пробелы более рекурсивно и более понятным для пользователя.
CREATE TABLE [dbo].[baseRecurrentes](
[ID] [nvarchar](8) NULL,
[INI] [datetime] NULL,
[FIN] [datetime] NULL
) ON [PRIMARY]
GO
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA1', CAST(0x0000A9C800000000 AS DateTime), CAST(0x0000A9E600000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA1', CAST(0x0000A9E700000000 AS DateTime), CAST(0x0000AA0200000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA1', CAST(0x0000AA0300000000 AS DateTime), CAST(0x0000AA2100000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA1', CAST(0x0000AA2200000000 AS DateTime), CAST(0x0000AA3F00000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA2', CAST(0x0000A9D600000000 AS DateTime), CAST(0x0000A9D900000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA2', CAST(0x0000A9EB00000000 AS DateTime), CAST(0x0000A9ED00000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA2', CAST(0x0000A9F000000000 AS DateTime), CAST(0x0000A9F100000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA3', CAST(0x0000AA1A00000000 AS DateTime), CAST(0x0000AA5A00000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA4', CAST(0x0000A9CA00000000 AS DateTime), CAST(0x0000A9CB00000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA5', CAST(0x0000A8DC00000000 AS DateTime), CAST(0x0000A8F100000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA5', CAST(0x0000A8F200000000 AS DateTime), CAST(0x0000A90F00000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA5', CAST(0x0000A91000000000 AS DateTime), CAST(0x0000A92E00000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA5', CAST(0x0000A92F00000000 AS DateTime), CAST(0x0000A94D00000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA5', CAST(0x0000A94E00000000 AS DateTime), CAST(0x0000A96B00000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA5', CAST(0x0000A96C00000000 AS DateTime), CAST(0x0000A98A00000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA5', CAST(0x0000A98B00000000 AS DateTime), CAST(0x0000A9A800000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA5', CAST(0x0000A9A900000000 AS DateTime), CAST(0x0000A9C700000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA5', CAST(0x0000A9C800000000 AS DateTime), CAST(0x0000A87900000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA5', CAST(0x0000A9E700000000 AS DateTime), CAST(0x0000AA0200000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA5', CAST(0x0000AA0300000000 AS DateTime), CAST(0x0000AA2100000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA5', CAST(0x0000AA2200000000 AS DateTime), CAST(0x0000AA3F00000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA5', CAST(0x0000AA4000000000 AS DateTime), CAST(0x0000AA5000000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA6', CAST(0x0000AA0900000000 AS DateTime), CAST(0x0000AA2900000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA7', CAST(0x0000A96C00000000 AS DateTime), CAST(0x0000A98A00000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA7', CAST(0x0000A98B00000000 AS DateTime), CAST(0x0000A9A800000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA7', CAST(0x0000A9A900000000 AS DateTime), CAST(0x0000A9C700000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA7', CAST(0x0000A85B00000000 AS DateTime), CAST(0x0000A87900000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA7', CAST(0x0000A9E700000000 AS DateTime), CAST(0x0000AA0200000000 AS DateTime))
INSERT [dbo].[baseRecurrentes] ([ID], [INI], [FIN]) VALUES (N'PERSONA7', CAST(0x0000AA0300000000 AS DateTime), CAST(0x0000AA2100000000 AS DateTime))
;WITH CTE AS (
SELECT *, RN = ROW_NUMBER()OVER(PARTITION BY ID ORDER BY INI DESC)
FROM BASERECURRENTES
), CTE2 AS (
--
SELECT DISTINCT T.ID,
--
CAST(T2.INI AS DATETIME) AS INI1, CAST(T2.FIN AS DATETIME) AS FIN1,
--
CAST(T3.INI AS DATETIME) AS INI2, CAST(T3.FIN AS DATETIME) AS FIN2,
--
CAST(T4.INI AS DATETIME) AS INI3, CAST(T4.FIN AS DATETIME) AS FIN3
--
FROM CTE T
LEFT JOIN CTE T2 ON T.ID = T2.ID AND T2.RN = 1
LEFT JOIN CTE T3 ON T.ID = T3.ID AND T3.RN = 2
LEFT JOIN CTE T4 ON T.ID = T4.ID AND T4.RN = 3
), CTE3 AS (
SELECT *, MSG = (CASE
--NO GAPS ON 3 LOGS
WHEN (INI1 - 1 BETWEEN INI2 AND FIN2) AND (INI2 - 1 BETWEEN INI3 AND FIN3) THEN 'SEC2'
--NO GAPS ON 2 LOGS
WHEN (INI1 - 1 BETWEEN INI2 AND FIN2) THEN 'SEC1'
--NO GAP AT ALL
ELSE 'NO SEC'
END)
FROM CTE2
)
SELECT * FROM CTE3
ORDER BY ID ASC
Я ожидаю таблицу с идентификатором пользователя, "днями разрыва" (сумма незарегистрированныхвремя) и сообщение, показывающее, где пробелы.
ID GD MSG
-------------------
PERSONA2 5 GAP ON X-Y