were type tutorial tls support servers found espaƱol engine enable sql sql-server tsql sql-server-2012

type - sql server 2017



Consigue la diferencia entre dos veces para SQL Server 2012 (3)

En su ejemplo, tendrá un problema cuando un cliente lo visitaría una vez, y al usar el programa lag / lead obtendrá la información de visita de otro cliente.

Intentalo:

SELECT T1.[User], T1.[CustomerID], T1.[Area], T1.[Event], T1.[VisitNumber], T1.[CurrentRoom], T1.[NewRoom], T1.[Time], (select TOP (1) t.Time from #beds t where t.[CustomerID] = T1.[CustomerID] and t.Time<T1.Time order by t.Time desc) PreviousTime, (select TOP (1) t.Time from #beds t where t.[CustomerID] = T1.[CustomerID] and t.Time>T1.Time order by t.Time) NextTime FROM #beds t1 WHERE T1.[Area] = ''Area2'' AND T1.[CurrentRoom] IS NOT NULL AND T1.[NewRoom] IS NOT NULL AND T1.[CustomerID] IS NOT NULL AND T1.[CustomerID] <> '' '' AND T1.Event IN (1,9) ORDER BY VisitNumber DESC

El fondo:

Estoy tratando de identificar la cantidad de tiempo que un cliente pasa en una habitación en particular. Cada Cliente es identificable por un CustomerID , y cuando lo visitan se les asigna un VisitNumber . Por ejemplo, si el cliente lo visitara hoy, obtendrían un VisitNumber de 111111. Se irían y volverían la próxima semana y tendrían un VisitNumber de 111112.

Cuando un cliente visita por primera vez, inicialmente no se les asigna una habitación, y cuando finalmente se les asigna su habitación designada, se escribe una entrada en la base de datos. CurrentRoom estaría en blanco ya que aún no tienen una habitación, y NewRoom es la habitación a la que se han trasladado.

Esta entrada se registraría como evento 1 (El cliente se mudó de una habitación a otra) y la hora es cuando se realiza la transacción. Si el cliente se traslada en el futuro durante su estadía existente , se registrará como evento 9 (El cliente se trasladó de una habitación a otra habitación) y los valores de CurrentRoom y * NewRoom también se registrarán.

El problema

Me las arreglé para obtener el tiempo de la fila anterior y el tiempo de la siguiente fila con LAG y LEAD y luego calcular la diferencia entre las dos veces, lo que me da el tiempo que el cliente pasó en esa habitación en particular.

El problema al utilizar LAG es que está obteniendo el valor anterior, que en algunos casos podría ser el valor de un cliente completamente diferente. Me gustaría obtener los valores de LAG y LEAD solo para un CustomerID particular y el VisitNumber actual y luego calcular la diferencia entre los valores para averiguar cuánto tiempo pasó el cliente en una habitación.

Datos de demostración:

CREATE TABLE #beds ( [id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY, [User] [nvarchar](50) NULL, [CustomerID] [nvarchar](50) NULL, [Area] [nchar](10) NULL, [Event] [nvarchar](50) NULL, [VisitNumber] [nvarchar](50) NULL, [Time] [datetime] NULL, [CurrentRoom] [nvarchar](50) NULL, [NewRoom] [nvarchar](50) NULL ) GO INSERT INTO #beds ([User],[CustomerID],[Area],[Event],[VisitNumber],[Time],[CurrentRoom],[NewRoom]) VALUES (''00001'',''C11111111'',''Area1'',2,111111111,''2017-03-22 11:05:44.360'',''B22'',''B44''), (''00001'',''C11111111'',''Area1'',1,111111111,''2017-03-22 11:05:15.517'','''',''B22''), (''00001'',''C22222222'',''Area2'',1,222222222,''2017-03-22 07:38:16.117'','''',''POD3''), (''00001'',''C22222222'',''Area2'',3,222222222,''2017-03-22 07:41:24.787'',''POD3'',''POD3''), (''00001'',''C22222222'',''Area2'',9,222222222,''2017-03-22 09:10:49.697'',''POD3'',''''), (''00001'',''C22222222'',''Area2'',1,222222222,''2017-03-22 10:05:19.130'','''',''POD15''), (''00001'',''C22222222'',''Area2'',2,222222222,''2017-03-22 10:13:43.057'',''POD15'',''A''), (''00001'',''C22222222'',''Area2'',3,222222222,''2017-03-22 10:25:01.527'',''A'',''A''), (''00001'',''C22222222'',''Area2'',3,222222222,''2017-03-22 10:46:03.960'',''A'',''A''), (''00001'',''C22222222'',''Area2'',3,222222222,''2017-03-22 10:46:17.030'',''A'',''A''), (''00002'',''C33333333'',''Area3'',1,333333333,''2017-03-22 09:20:23.660'','''',''B46''), (''00001'',''C33333333'',''Area2'',9,333333333,''2017-03-22 08:53:32.860'',''POD8'',''POD1''), (''00001'',''C33333333'',''Area2'',1,333333333,''2017-03-22 07:34:58.810'',''POD7'',''POD8''), (''00001'',''C33333333'',''Area2'',1,333333333,''2017-03-22 11:49:55.203'','''',''BB4''), (''00001'',''C33333333'',''Area2'',3,333333333,''2017-03-22 11:50:11.943'',''BB4'',''BB4''), (''00001'',''C33333333'',''Area2'',3,333333333,''2017-03-22 08:42:56.157'',''POD8'',''POD8''), (''00001'',''C33333333'',''Area2'',3,333333333,''2017-03-22 08:22:59.157'',''POD8'',''POD8''), (''00003'',''C33333333'',''Area3'',1,333333333,''2017-03-23 06:41:12.753'','''',''B46'') GO

Esta es la consulta que tengo hasta ahora; esto me dará el valor de la fila anterior y el valor de la fila siguiente, pero no creo que tenga en cuenta al cliente.

SELECT T1.[User], T1.[CustomerID], T1.[Area], T1.[Event], T1.[VisitNumber], T1.[CurrentRoom], T1.[NewRoom], T1.[Time], LAG(T1.TIME) OVER (ORDER BY T1.VisitNumber) PreviousTime, LEAD(T1.TIME) OVER (ORDER BY T1.VisitNumber) NextTime FROM #beds t1 WHERE T1.[Area] = ''Area2'' AND T1.[CurrentRoom] IS NOT NULL AND T1.[NewRoom] IS NOT NULL AND T1.[CustomerID] IS NOT NULL AND T1.[CustomerID] <> '' '' AND T1.Event IN (1,9) ORDER BY VisitNumber DESC

Salida esperada: esta es la salida que estoy esperando. Solo quiero el TimeInRoom (excluyendo el campo de fecha de la hora):

+------------+-------+-------------+-------------+---------+------------+ | CustomerID | Area | VisitNumber | CurrentRoom | NewRoom | TimeInRoom | +------------+-------+-------------+-------------+---------+------------+ |C33333333 |Area2 | 333333333 | | BB4 | 00:10 | |C33333333 |Area2 | 333333333 | | POD8 | 00:20 | |C33333333 |Area2 | 333333333 | POD8 | | 00:30 | +------------+-------+-------------+-------------+---------+------------+


Espero que esto ayude:

;WITH cte_Result AS ( SELECT [CustomerID], [Area], [VisitNumber], [CurrentRoom], [NewRoom], [Time], LAG([TIME]) OVER (partition by [CustomerID],[VisitNumber] ORDER BY ID DESC) PreviousTime, LEAD([TIME]) OVER (partition by [CustomerID],[VisitNumber] ORDER BY ID DESC) NextTime FROM #beds WHERE [Area] = ''Area2'' AND [CurrentRoom] IS NOT NULL AND [NewRoom] IS NOT NULL AND [CustomerID] IS NOT NULL AND [CustomerID] <> '' '' AND [Event] IN (1,9) --AND [CustomerID] = ''C33333333'' ), cte_BuildStayPeriod AS ( SELECT CustomerID, Area, VisitNumber, CurrentRoom, NewRoom, DATEDIFF(SECOND, COALESCE([NextTime], PreviousTime), COALESCE(PreviousTime, [time])) AS StayDuration FROM cte_Result ) SELECT CustomerID, Area, VisitNumber, CurrentRoom, NewRoom, StayDuration, CAST(DATEADD(SECOND, StayDuration, ''1900-01-01'') AS TIME) AS StayDuration FROM cte_BuildStayPeriod


Puede que no haya entendido muy bien su pregunta, pero intente usar la cláusula PARTITION BY dentro de sus funciones LAG / LEAD:

,LAG(T1.TIME) OVER (PARTITION BY CustomerID ORDER BY T1.VisitNumber) PreviousTime ,LEAD(T1.TIME) OVER (PARTITION BY CustomerID ORDER BY T1.VisitNumber) NextTime