[英]calculate total minutes between two timestamps across multiple records using postgresql
[英]Sql total minutes between records
我正在嘗試進行查詢,以返回一個人工作的分鍾數。 一個人在同一天可以有很多出入。 我想知道進入和離開之間的總分鍾數。
例如:我希望20498090R返回79分鍾
我嘗試使用此查詢,但效果不佳:
SELECT Empleado,
DATEDIFF("mi", Hora, NextDate)
FROM ( SELECT Empleado,
Hora,
( SELECT MIN(Hora)
FROM [dbo].[Fichajes] T2
WHERE T2.Empleado = T1.Empleado
AND T2.Hora > T1.Hora
) AS NextDate
FROM [dbo].[Fichajes] T1
) AS T
使用此查詢:
12212332W -->
20498090R --> 4
41435568N --> 6
20498090R --> 7055
41435568N -->
20498090R --> 75
20498090R -->
根據員工和時間戳排序的登錄表創建CTE,並分配行號。 現在,您可以將該CTE加入其自身,以僅查找員工登錄和注銷的行。 然后,您可以找到工作的分鍾,並將它們加起來。
;with cte
as (select f.Empleado, f.Hora, f.Entrada, ROW_NUMBER() over (order by f.Empleado, f.Hora) RowNum
from Fichajes f)
select c1.Empleado, SUM(DATEDIFF(mi, c1.Hora, c2.Hora)) MinutesWorked
from cte c1
join cte c2 on c2.Empleado = c1.Empleado and c2.RowNum = c1.RowNum + 1 and c1.Entrada = 1 and c2.Entrada = 0
group by c1.Empleado
使用游標是這樣的:
DECLARE @LV_EMP_CUR游標
十進制@LV_EMP VARCHAR(32)
十進制@LV_MINUTES FLOAT
SET @ LV_EMP_CUR = CURSOR FOR SELECT Emppleado from TABLE_NAME
OPEN @LV_EMP_CUR FETCH NEXT FROM @LV_EMP_CUR INTO @LV_EMP
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @DT DATETIME
SET @DT = (SELECT HORA FROM TABLE_NAME WHERE EMPLEADO=@LV_EMP)
SET @LV_MINUTES= @LV_MINUTES + SELECT CAST(@DT AS TIME)
FETCH NEXT FROM @LV_EMP_CUR INTO @LV_EMP
END
CLOSE @LV_EMP_CUR
DEALLOCATE @LV_EMP_CUR
我已使用sql窗口函數LEAD查找下一條記錄,並按用戶和日期進行了分區。 然后計算同一用戶兩次,同一日期兩次之間的工作時間。
將數據插入到臨時表中以分組依據,並獲得總工作時間。 您可以使用SELECT * FROM #tempTime; 在最終選擇查詢之前,先查看結果進入臨時表的內容。 它給出了代碼是否正常工作的想法。
最終代碼:
IF OBJECT_ID('dbo.Fichajes') IS NULL
CREATE TABLE dbo.Fichajes(
[Empleado] [varchar](20) NULL,
[Obra] [varchar](20) NULL,
[Hora] [datetime2](7) NULL,
[Entrada] [bit] NULL,
[Motivo] [varchar](20) NULL,
[Activated] [bit] NULL
)
;
INSERT [dbo].[Fichajes] ([Empleado], [Obra], [Hora], [Entrada], [Motivo], [Activated]) VALUES (N'12212332W', N'PRY12345', CAST(N'2017-04-17 12:03:00.0000000' AS DateTime2), 1, NULL, NULL)
INSERT [dbo].[Fichajes] ([Empleado], [Obra], [Hora], [Entrada], [Motivo], [Activated]) VALUES (N'20498090R', N'PRY12345', CAST(N'2017-04-20 12:21:00.0000000' AS DateTime2), 1, NULL, NULL)
INSERT [dbo].[Fichajes] ([Empleado], [Obra], [Hora], [Entrada], [Motivo], [Activated]) VALUES (N'20498090R', N'PRY12345', CAST(N'2017-04-20 12:25:00.0000000' AS DateTime2), 0, NULL, NULL)
INSERT [dbo].[Fichajes] ([Empleado], [Obra], [Hora], [Entrada], [Motivo], [Activated]) VALUES (N'41435568N', N'PRY12345', CAST(N'2017-04-20 12:23:00.0000000' AS DateTime2), 1, NULL, NULL)
INSERT [dbo].[Fichajes] ([Empleado], [Obra], [Hora], [Entrada], [Motivo], [Activated]) VALUES (N'41435568N', N'PRY12345', CAST(N'2017-04-20 12:29:00.0000000' AS DateTime2), 0, NULL, NULL)
INSERT [dbo].[Fichajes] ([Empleado], [Obra], [Hora], [Entrada], [Motivo], [Activated]) VALUES (N'20498090R', N'PRY12345', CAST(N'2017-04-25 10:00:00.0000000' AS DateTime2), 1, NULL, NULL)
INSERT [dbo].[Fichajes] ([Empleado], [Obra], [Hora], [Entrada], [Motivo], [Activated]) VALUES (N'20498090R', N'PRY12345', CAST(N'2017-04-25 11:15:00.0000000' AS DateTime2), 0, NULL, NULL)
IF OBJECT_ID('tempdb..#tempTime') IS NOT NULL DROP TABLE #tempTime;
with c1 AS
(
SELECT
[Empleado]
,[Obra]
,[Entrada]
,[Motivo]
,[Activated]
,CONVERT(date, Hora) AS [Date]
,CONVERT(time, Hora, 114) AS [Time]
,[Hora]
FROM [dbo].[Fichajes]
)
SELECT
[Empleado]
,[Hora]
,LAG( [Hora]) OVER(PARTITION BY [Empleado], [Date] ORDER BY [Empleado], [Hora] ASC) AS PreviousRecord
,LEAD( [Hora]) OVER(PARTITION BY [Empleado], [Date] ORDER BY [Empleado], [Hora] ASC) AS NextRecord
,DATEDIFF(MINUTE, [Hora], LEAD( [Hora]) OVER(PARTITION BY [Empleado], [Date] ORDER BY [Empleado], [Hora] ASC)) AS [Minutes]
INTO #tempTime
FROM c1
;
SELECT
[Empleado]
,SUM([Minutes]) AS WorkingMinutes
FROM #tempTime
GROUP BY [Empleado]
;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.