具有一个日期列的同一表中两个位置之间的日期差

时间:2018-08-01 16:07:59

标签: sql sql-server tsql sql-server-2012

标签将实际放置在客户端位置,并将在这些位置移动。我需要找到放置在一个位置的时间。例如,如果标签在上午10点放置在位置1,并在10:15移动到位置2,则时差为15分钟。这是我有的示例数据

create table #Tagm (tagname varchar(10),created_date datetime ,Loc int )

insert into #Tagm values ('AC1', '2018-07-01 09:35:37.370' ,56)
,( 'AC1', '2018-07-01 10:35:37.370' ,64),( 'AC1', '2018-07-01 10:55:37.370' ,84),( 'AC1', '2018-07-01 11:55:37.370' ,76)

我尝试了这个,但这给了我所有位置的数量

select tagname ,DATEDIFF(MINUTE, min(created_date),max(created_date) )as totaltime 
from #Tagm 
group by tagname 

我要寻找的结果如下所示

enter image description here

任何帮助将不胜感激

3 个答案:

答案 0 :(得分:0)

我认为您只想要lead()

SELECT tagname,
       DATEDIFF(MINUTE, 
                created_date, 
                LEAD(created_date) OVER (PARTITION BY tagname
                                         ORDER BY created_date
                                        )
              ) AS totaltime
FROM #Tagm t;

答案 1 :(得分:0)

由于您提到有可能连续多次出现相同的位置,因此您需要在该位置找到时间的真实开始和结束时间。通过使用LAG,您可以执行与其他答案之一相似的操作。找到真正的起点和终点之后,您就可以抓住不同之处。可以在不太常用的表表达式中或作为子查询来完成此操作,但是我将它拆分成这样,以便您可以更轻松地看到逻辑。

我还添加了第二个标记名,并且位置保持不变的用例。

create table #Tagm (tagname varchar(10),created_date datetime ,Loc int )

insert into #Tagm values ('AC1', '2018-07-01 09:35:37.370' ,56), ('AC1', '2018-07-01 09:40:37.370' ,56) ,( 'AC1', '2018-07-01 10:35:37.370' ,64),( 'AC1', '2018-07-01 10:55:37.370' ,84),( 'AC1', '2018-07-01 11:55:37.370' ,76)
insert into #Tagm values ('AC2', '2018-08-01 09:35:37.370' ,56), ('AC2', '2018-08-01 09:40:37.370' ,64) ,( 'AC2', '2018-08-01 10:35:37.370' ,64),( 'AC2', '2018-08-01 10:55:37.370' ,84),( 'AC2', '2018-08-01 11:55:37.370' ,76)

;WITH cte AS (
    SELECT
       *
       ,LAG(Loc) OVER (PARTITION BY tagname ORDER BY created_date) as PrevLoc
    FROM
       #Tagm
)

, cteLocationStart AS (
    SELECT
       *
       ,IIF(PrevLoc IS NULL or PrevLoc <> Loc, 1,0) as StartSequence
    FROM
       cte
)

SELECT 
    s.tagname
    ,s.Loc
    ,s.created_date as StartDateTime
    ,MIN(n.created_date) as EndDateTime
    ,DATEDIFF(MINUTE,s.created_date, MIN(n.created_date)) as TotalTime
FROM
    cteLocationStart s
    LEFT JOIN cteLocationStart n
    ON s.tagname = n.tagname
    AND s.created_date < n.created_date
    AND n.StartSequence = 1
WHERE
    s.StartSequence = 1
GROUP BY
    s.tagname
    ,s.Loc
    ,s.created_date
ORDER BY
    tagname
    ,StartDateTime

答案 2 :(得分:0)

with CTE as 
(select  row_number() over (order by created_date desc) as rn, created_date, tagname,loc from #Tagm
)
SELECT t1.loc,t1.created_date, t1.tagname, ISNULL(DATEDIFF(mi, t1.created_date, t2.created_date), NULL) 
AS seconds FROM CTE t1 
LEFT JOIN CTE t2 
ON t1.rn = t2.rn + 1 ORDER BY t1.created_date