Sql记录之间的总分钟数

Sql记录之间的总分钟数,sql,sql-server,Sql,Sql Server,我试图做一个查询,返回一个人工作的分钟数。一个人可以在同一天有许多出入口。我想知道从入口到出口的总分钟数 下面是桌子的图片: 例如:我希望20498090R返回79分钟 我尝试使用此查询,但效果不佳: SELECT Empleado, DATEDIFF("mi", Hora, NextDate) FROM ( SELECT Empleado, Hora, ( SELECT MIN(Hora)

我试图做一个查询,返回一个人工作的分钟数。一个人可以在同一天有许多出入口。我想知道从入口到出口的总分钟数

下面是桌子的图片:

例如:我希望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 --> 

使用如下类似的游标:

声明@LV\u EMP\u CUR游标 声明@LV_EMP VARCHAR32

宣布@LV_分钟浮动

将@LV\U EMP\U CUR=光标设置为 从表_NAME中选择Empleado

                    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

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

我使用了一个sql窗口函数LEAD来查找下一条记录,并按用户和日期进行分区。然后计算同一用户和同一日期两次之间的工作分钟数

将数据插入临时表以分组并获取总工作分钟数。您可以使用SELECT*FROM TENTIME;在最后的select查询之前,查看进入临时表的结果。它给出了代码是否正常工作的想法

最终代码:


@jarlh MSSQL,但sql在endMySQL和MS sql Server上是否具有不同的日期/时间功能。@jarlh很抱歉造成混淆,第一篇文章是我的问题解释:如何使用20498090R返回79?
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]
;