2017-04-25 55 views
0

我正在尝试进行一个查询,该查询返回一个人工作的分钟数。一个人可以有很多条目并在同一天退出。我想知道进入和退出之间的总分钟数。Sql记录间总分钟数

这里表的图片:TABLE

例如:我想为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 --> 
+0

@jarlh MSSQL,但SQL末 – Pablo

+0

MySQL和MS SQL服务器有不同的日期/时间的功能。 – jarlh

+0

@jarlh对不起,第一篇文章是我的查询 – Pablo

回答

1

从登录表中创建一个由员工排序的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 

DEMO

+0

你是我的上帝!它工作完美。 – Pablo

0

使用Cursers东西LIK E该:

DECLARE @LV_EMP_CUR CURSOR
DECLARE @LV_EMP VARCHAR(32)

DECLARE @LV_MINUTES FLOAT

SET @ LV_EMP_CUR = CURSOR FOR SELECT FROM Empleado 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 [email protected]_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 
0

我已经使用了SQL窗函数导致寻找下一个记录,由用户和天分割。然后计算同一用户和同一日期的两次之间的工作分钟。

将数据插入到临时表中以获取总工作分钟数。您可以使用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] 
;