根据LAG更改输出

时间:2017-08-07 12:33:36

标签: sql-server sql-server-2008

我有当前的问题:

我试图让每个工人在一天工作的时间来计算我们公司的生产力。我们每个工人都有时间进入并离开大楼。 规则是,有时我们的工人离开建筑物抽烟或从外面的新闻台得到一些东西,所以我们不会考虑到这一点并计算好像这个人从未离开过建筑物。

我们的大楼里有一个自助餐厅,所以大多数人实际上都没有离开大楼吃午餐/晚餐,所以我们只需要从他们的生产力计算中删除1小时,但是,如果他们离开超过45分钟,我们会考虑工人离开午餐/晚餐。

我需要最终结果如下:

+----------+----------------+----------------+---------+----------+
| PersonID |       IN       |      OUT       | MINUTES |  EatOut  |
+----------+----------------+----------------+---------+----------+
|     1    | 20170807 08:00 | 20170807 17:25 |   465   |     1    |
+----------+----------------+----------------+---------+----------+
|     2    | 20170807 08:00 | 20170807 17:00 |   540   |     0    |
+----------+----------------+----------------+---------+----------+

到目前为止我的查询:

DECLARE @mytable TABLE(
    PersonId INT,
    Situation VARCHAR(3),
    SituationDtm DATETIME
);

INSERT INTO @mytable VALUES
(1, 'IN', '20170807 08:00'),
(1, 'OUT', '20170807 12:30'),
(1, 'IN', '20170807 14:00'),
(1, 'OUT', '20170807 17:15'),
(2, 'IN', '20170807 08:00'),
(2, 'OUT', '20170807 09:15'),
(2, 'IN', '20170807 09:30'),
(2, 'OUT', '20170807 17:00');

WITH CTE AS (
    SELECT
        [PersonId],
        Situation AS 'CUR.Situation',
        SituationDtm AS 'CUR.SituationDtm',
        LEAD(Situation) OVER(PARTITION BY PersonId ORDER BY SituationDtm) AS 'NEXT.Situation',
        LEAD(SituationDtm) OVER(PARTITION BY PersonId ORDER BY SituationDtm) AS 'NEXT.SituationDtm'
    FROM
        @mytable
)
SELECT
    [CUR.Situation],
    [CUR.SituationDtm],
    [NEXT.Situation],
    [NEXT.SituationDtm],
    DATEDIFF(MINUTE, [CUR.SituationDtm], [NEXT.SituationDtm]) AS 'MINUTES'
FROM
    CTE

提前致谢

1 个答案:

答案 0 :(得分:1)

您可以进一步查询如下:由于您在SQL Server 2008中查找没有超前/滞后的解决方案,因此可以查询如下:

;With Cte as (
    Select *, RowN = Row_Number() over(Partition by PersonId order by SituationDtm) from #mytable
), Cte2 as (
    Select c1.*, c2.Situation as NextSituation, c2.SituationDtm as NextSituationDtm from cte c1 left join cte c2 on c1.RowN+1 = c2.RowN
    and c1.PersonId = c2.PersonId
)
Select  PersonId, 
Min(SituationDTM) as [In],
Max(Situationdtm) as [Out],
Sum(Case when Situation = 'OUT' and NextSituation = 'IN' and datediff(mi,SituationDtm, NextSituationDTM) > 60 then 1 else 0 end) EatOut,
Sum(Case when Situation = 'OUT' and NextSituation = 'IN' and datediff(mi,SituationDtm, NextSituationDTM) > 60 then 0 else datediff(mi,SituationDtm, NextSituationDTM)  end) as [minutes]
from Cte2
group by PersonId

在> = 2012之后的更高版本中,您可以按以下方式查询:

Select  PersonId, 
Min(SituationDTM) as [In],
Max(Situationdtm) as [Out],
Sum(Case when Situation = 'OUT' and NextSituation = 'IN' and datediff(mi,SituationDtm, NextSituationDTM) > 60 then 1 else 0 end) EatOut,
Sum(Case when Situation = 'OUT' and NextSituation = 'IN' and datediff(mi,SituationDtm, NextSituationDTM) > 60 then 0 else datediff(mi,SituationDtm, NextSituationDTM)  end) as [minutes]
 from (
    Select *, NextSituationDTM = lead(situationdtm) over (partition by personid order by situationdtm), 
    NextSituation = lead(Situation) over (partition by personid order by situationdtm) from #mytable
) a
group by PersonId

输出如下:


+----------+-------------------------+-------------------------+--------+---------+
| PersonId |           In            |           Out           | EatOut | minutes |
+----------+-------------------------+-------------------------+--------+---------+
|        1 | 2017-08-07 08:00:00.000 | 2017-08-07 17:15:00.000 |      1 |     465 |
|        2 | 2017-08-07 08:00:00.000 | 2017-08-07 17:00:00.000 |      0 |     540 |
+----------+-------------------------+-------------------------+--------+---------+