夏季时间

时间:2019-02-21 08:26:32

标签: sql sql-server

我只有大量的技术数据,可以是OnSite或OnTheWay, 我想在他们去过的巫婆遗址里度过夏天,并且住了多久。 示例:

id        UpdateTime            UserName    SiteID
488565  2019-02-18 19:07:24.000 stephen      null
488388  2019-02-18 17:34:52.000 stephen      297
488558  2019-02-18 18:06:48.000 stephen      297
488565  2019-02-18 18:07:24.000 stephen      297
488565  2019-02-18 14:07:24.000 stephen      null
483170  2019-02-18 13:53:14.000 stephen      299
488565  2019-02-18 11:07:24.000 stephen      null
483170  2019-02-18 10:53:14.000 stephen      297

今天两次技术在297次,我想按每种技术获得此结果(结束时间是我获得Null或Diffrent SiteID的时间):

UserName    InComeTime                 TimeInSite(min)     SiteID
stephen      2019-02-18 10:53:14.000     14                 297
stephen      2019-02-18 13:53:14.000     14                 299
stephen      2019-02-18 17:34:52.000     153                 297

谢谢,

2 个答案:

答案 0 :(得分:0)

不能发表评论,因为没有声誉:(?!?,所以尽管有一些问题,我还是作为答案发表。原则上,您可以按照将空值站点记录连接到非空站点记录的方式进行工作。您不能保证null值的siteIds表示“退出”,非null的siteIds表示条目,那么就没有“起点”,因此您需要进行表扫描。如果您可以保证它(或单独处理异常),则查询可以采用以下形式:

select t1.UserName, 
    t1.UpdateTime as EntryTime, 
    t2.UpdateTime as ExitTime, 
    datediff(MI, t1.UpdateTime, t2.UpdateTime) as TimeInSite, 
    t1.SiteId
from TimeTable t1
join TimeTable t2 on t2.id in 
    (select id from TimeTable 
        where 
            -- want the same user
            UserName = t1.UserName
            -- site id null/different means 'exited site'
            and (siteId is null)  
            -- now get the entry with the minium update time that is greater than the entry time
            and UpdateTime = (select min(UpdateTime) from TimeTable where UpdateTime > t1.UpdateTime
        )
    )
where t1.SiteId is not null
order by EntryTime

这没有考虑到您可以为同一次访问(即三个297s)具有多个“非空” siteId。理想情况下,应避免这种情况。如果不能,则可以先将这些条目整理到临时表中,以仅选择第一个条目时间。

以上查询输出以下内容(SQL Server,请注意,为清楚起见,我添加了进入和退出时间)。由于存在多个297,这并不是您想要的100%,但是也许它可以帮助您入门。现在,时间不够了,也许其他人可以提供100%的解决方案。祝你好运!

UserName     EntryTime               ExitTime                TimeInSite  SiteId
------------ ----------------------- ----------------------- ----------- -----------
stephen      2019-02-18 10:53:14.000 2019-02-18 11:07:24.000 14          297
stephen      2019-02-18 13:53:14.000 2019-02-18 14:07:24.000 14          299
stephen      2019-02-18 18:07:24.000 2019-02-18 19:07:24.000 60          297

答案 1 :(得分:0)

您可以使用窗口功能执行此操作。您要为行分配组,然后进行汇总。如何定义分组?

在这种情况下,您要在组中包括下一个NULL值。因此,对您有用的定义是按相反顺序累积的NULL个值的数量。那就是:

select t.*,
       sum(case when siteId is null then 1 else 0 end) over (partition by userName order by updatetime desc) as grp
from t;

然后,您可以汇总以获得所需的内容:

select username, min(siteid) as siteid,
       min(updatetime) as incometime,
       datediff(minute, min(updatetime), max(updatetime)) as minutes
from (select t.*,
             sum(case when siteId is null then 1 else 0 end) over (partition by userName order by updatetime desc) as grp
      from t
     ) t;