SQL Server在不同行之间查找datediff,求和 [英] SQL Server find datediff between different rows, sum

查看:75
本文介绍了SQL Server在不同行之间查找datediff,求和的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试建立一个查询,以分析我们的时间跟踪系统中的数据。每次用户向内或向外滑动时,都会记录记录滑动时间以及打开或关闭站点(进入或退出)。在用户 Joe Bloggs的情况下,有4行,我想配对并计算Joe Bloggs在网站上花费的总时间。

I am trying to build a query that analyzes data in our time tracking system. Every time a user swipes in or out, it makes a row recording the swipe time and On or Off site (entry or exit). In user 'Joe Bloggs' case there are 4 rows, which I want to pair and calculate a total time spent on site for Joe Bloggs.

问题是难以配对的记录。在给定的示例中,第二个用户有两个连续的 on,我需要找到一种方法来忽略重复的 on或 off行。

The problem is that there are records that are not as easy to pair. In the example given, the second user has two consecutive 'on's, and I need to find a method for ignoring repeated 'on' or 'off' rows.

ID  | Time                    |OnOffSite| UserName   
------------------------------------------------------
123 | 2011-10-25 09:00:00.000 | on      | Bloggs Joe |
124 | 2011-10-25 12:00:00.000 | off     | Bloggs Joe |
125 | 2011-10-25 13:00:00.000 | on      | Bloggs Joe |
126 | 2011-10-25 17:00:00.000 | off     | Bloggs Joe |
127 | 2011-10-25 09:00:00.000 | on      | Jonesy Ian |
128 | 2011-10-25 10:00:00.000 | on      | Jonesy Ian |
129 | 2011-10-25 11:00:00.000 | off     | Jonesy Ian |
130 | 2011-10-25 12:00:00.000 | on      | Jonesy Ian |
131 | 2011-10-25 15:00:00.000 | off     | Jonesy Ian |

我的系统是MS SQL2005。查询的报告时间是每月。

My System is MS SQL 2005. The reporting period for the query is Monthly.

有人可以提出解决方案吗?我的数据已经按用户名和时间分组在一个表中,并且ID字段为身份。

Can anyone suggest a solution? my data is already grouped in a table by Username and time, with the ID field being Identity.

推荐答案

-- =====================
-- sample data
-- =====================
declare @t table
(
    ID int,
    Time datetime,
    OnOffSite varchar(3),
    UserName varchar(50)
)

insert into @t values(123, '2011-10-25 09:00:00.000', 'on', 'Bloggs Joe')
insert into @t values(124, '2011-10-25 12:00:00.000', 'off', 'Bloggs Joe')
insert into @t values(125, '2011-10-25 13:00:00.000', 'on', 'Bloggs Joe')
insert into @t values(126, '2011-10-25 17:00:00.000', 'off', 'Bloggs Joe')
insert into @t values(127, '2011-10-25 09:00:00.000', 'on', 'Jonesy Ian')
insert into @t values(128, '2011-10-25 10:00:00.000', 'on', 'Jonesy Ian')
insert into @t values(129, '2011-10-25 11:00:00.000', 'off', 'Jonesy Ian')
insert into @t values(130, '2011-10-25 12:00:00.000', 'on', 'Jonesy Ian')
insert into @t values(131, '2011-10-25 15:00:00.000', 'off', 'Jonesy Ian')

-- =====================
-- solution
-- =====================
select
    UserName, timeon, timeoff, diffinhours = DATEDIFF(hh, timeon, timeoff)
from
(
    select
        UserName,
        timeon = max(case when k = 2 and OnOffSite = 'on' then Time end),
        timeoff = max(case when k = 1 and OnOffSite = 'off' then Time end)
    from
    (
        select
            ID,
            UserName,
            OnOffSite,
            Time,
            rn = ROW_NUMBER() over(partition by username order by id)
        from
        (
            select
                ID,
                UserName,
                OnOffSite,
                Time,
                rn2 = case OnOffSite 
                -- '(..order by id)' takes earliest 'on' in the sequence of 'on's
                -- to take the latest use '(...order by id desc)'
                when 'on' then 
                    ROW_NUMBER() over(partition by UserName, OnOffSite, rn1 order by id)
                -- '(... order by id desc)' takes the latest 'off' in the sequence of 'off's
                -- to take the earliest use '(...order by id)'
                when 'off' then
                    ROW_NUMBER() over(partition by UserName, OnOffSite, rn1 order by id desc)
                end,
                rn1
            from
            (
                select
                    *,
                    rn1 = ROW_NUMBER() over(partition by username order by id) +
                        ROW_NUMBER() over(partition by username, onoffsite order by id desc)
                from @t
            ) t
        ) t
        where rn2 = 1
    ) t1
    cross join
    (
        select k = 1 union select k = 2
    ) t2
    group by UserName, rn + k
) t
where timeon is not null or timeoff is not null
order by username

这篇关于SQL Server在不同行之间查找datediff,求和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆