/ / Kolejne obliczanie wartości między wierszami w tabeli - sql-server, tsql

Kolejno obliczyć wartość między wierszami w tabeli - sql-server, tsql

Próbuję przeprowadzić t-sql, który jest w stanie wykonać niektóre obliczenia, biorąc wartość datetime odejmowania kolejnych wierszy z wartości datetime poprzedniego.

Na przykład:

             Col1                            Col2
-------------------------------------------------------------------
row 1: | ENTRY_DOOR_CLOSE                | 2/12/2014 16:41:40:4140
row 2: | EXIT_DOOR_CLOSE_ENTRY_DOOR_OPEN | 3/12/2014 16:41:40:4140
row 3: | ENTRY_DOOR_CLOSE                | 4/12/2014 16:41:40:4140
row 4: | EXIT_DOOR_CLOSE_ENTRY_DOOR_OPEN | 5/12/2014 16:41:40:4140
--------------------------------------------------------------------

Wynik:

       Col1          Col2
---------------------------------------------------------------------
Row 1: | Diff   | Row2.DateTime - Row1.DateTime
Row 2: | Diff   | Row4.DateTime - Row3.DateTime
---------------------------------------------------------------------

Czy ktoś może zaproponować pomysł, aby rozwiązać ten problem?

Odpowiedzi:

2 dla odpowiedzi № 1

W SQL Server 2012+ możesz użyć lead() funkcjonować:

select "Diff" as col1,
datediff(second, col2, col2_next) as diff_in_seconds
from (select t.*, lead(col2) over (order by col2) as col2_next
from table t
) t
where col1 = "ENTRY_DOOR_CLOSE";

Zakłada się, że wartości są przeplatane, tak jak w pytaniu.


0 dla odpowiedzi nr 2

Po prostu zorientowałem się, że użycie CTE może rozwiązać mój problem w przypadku, gdy nie używam SQL 2k12

;WITH valuedTable AS (
SELECT
ROW_NUMBER() OVER (PARTITION BY ScxxID, SxxID ORDER BY RecordTime) AS RowID
, ScxxID
, SxxID
, Exxx
, RecordTime
, ProcessName
FROM
database..xxx
WHERE
ProcessName = "EXIT_DOOR_CLOSE_ENTRY_DOOR_OPEN"
OR
ProcessName = "ENTRY_DOOR_CLOSE"
)
SELECT
valuedTable.ProcessName
, valuedTable.RecordTime
, nex.ProcessName
, nex.RecordTime
, DATEDIFF(S, valuedTable.RecordTime, nex.RecordTime) DIFF
FROM
valuedTable
INNER JOIN
( valuedTable nex ON nex.RowID = valuedTable.RowID + 1 )
AND
( nex.ProcessName = "EXIT_DOOR_CLOSE_ENTRY_DOOR_OPEN" )

0 dla odpowiedzi № 3

jeśli korzystasz z serwera sql 2012 - użyj tego (Twoja tabela jest uporządkowana, ale ta jest również zmienna dla tabeli niezamówionej):

;WITH CTE AS (SELECT ROW_NUMBER() OVER (ORDER BY Col2) AS RN, Col1, Col2
FROM YourTable)

SELECT "Diff" AS Col1, DATEDIFF(HOUR,a.Col2,x.Col2) AS Col2
FROM CTE a
CROSS APPLY (SELECT TOP 1 Col2 FROM CTE b WHERE Col1 = "EXIT_DOOR_CLOSE_ENTRY_DOOR_OPEN" AND b.RN > a.RN ORDER BY Col2 ASC) x
WHERE Col1 = "ENTRY_DOOR_CLOSE"

0 dla odpowiedzi nr 4

Mam nadzieję, że to pomoże

--CREATE A TEMPORARY TABLE TO HOLD THE GIVEN DATA
DECLARE @Table AS TABLE
(
ID INT IDENTITY(1,1)
,Col1  VARCHAR(50)
,Col2 DATETIMEOFFSET(0)
)

INSERT INTO @Table (COl1,Col2) VALUES  ("ENTRY_DOOR_CLOSE", "2014-12-02"),
("EXIT_DOOR_CLOSE_ENTRY_DOOR_OPEN" , "2014-12-03")
,("ENTRY_DOOR_CLOSE","2014-12-04")
,("EXIT_DOOR_CLOSE_ENTRY_DOOR_OPEN" , "2014-12-05")

--Using common table expression do the following
;WITH CTE AS
(
SELECT

ROW_NUMBER() OVER (ORDER BY ID) AS RowID
,CONVERT(date,Col2) AS DateColumn

FROM @Table

)

SELECT
"DIF" AS Col1
,DATEDIFF(DD,SEcondCTE.DateColumn,FirstCTE.DateColumn)
FROM
CTE FirstCTE
INNER JOIN
CTE SEcondCTE
ON
FirstCTE.RowID = SEcondCTE.RowID + 1
WHERE FirstCTE.RowID % 2 =0