我正在使用MSSQL 2008 Standard
我在select命令中有多行,这些行充满了事件。对于每个事件我都有一个时间戳,现在我想计算事件之间的时间:
(number) | event | timestamp | duration
---------+----------------+---------------------+----------
1 | logon | 2012-05-23 10:00:00 |
2 | incomming call | 2012-05-23 10:01:00 |
3 | call ended | 2012-05-23 10:02:00 |
4 | logoff | 2012-05-23 10:04:00 |
(数字列不存在,但更容易解释)
现在第一行的持续时间单元格应为1,第二行的持续时间单元格应为1,第三行的持续时间单元格为2。
有没有人知道如何在没有循环的情况下实现这一点等等。
谢谢
答案 0 :(得分:3)
您需要自我加入。因为你需要生成一个id,然后像:
select t1.*, datediff(minute, t2.timestamp, t1.timestamp) from
(select *, row_number() over (order by ...) as rowid from MyTable) t1
inner join
(select *, row_number() over (order by ...) as rowid from MyTable) t2
on t1.rowid = t2.rowid - 1
答案 1 :(得分:1)
这是我当前的版本/解决方案:
declare @temp table
(
id int,
timestamp datetime,
type nvarchar(255),
skillname nvarchar(255),
event nvarchar(255),
userstatus nvarchar(255)
)
insert into @temp (id, timestamp, type, skillname, event, userstatus)
(
select ROW_NUMBER() over (order by timestamp) as id, * from
(
select TimeStamp, 'Event' as type, SkillName, Event, UserStatus from AgentEvents
where TimeStamp >= '2012-05-22T00:00:00'
and UserName like '%engel%'
union
select TimeStamp, 'Anruf' as type, SkillName, '' as event, '' as status from calls
where TimeStamp >= '2012-05-22T00:00:00'
and UserName like '%engel%'
) as a
)
select t1.*, DATEDIFF(second, t1.timestamp, t2.timestamp) as duration
from @temp t1
left outer join @temp t2 on t1.id = t2.id - 1
修改:将inner join
更改为left outer join
,否则最后一行将丢失。
答案 2 :(得分:1)
由于没有报告第一行,我发现提供的CTE答案不太理想。我发现连接的其他答案太复杂了。我将问题提炼到这个片段
以下是使用CTE的代码,在CTE的选择中创建一个序列,该序列通过有序时间戳标识行号。结果选择选择生成的有序行并确定分钟。
WITH AgentActions AS
(
select ROW_NUMBER() OVER (ORDER BY [TimeStamp]) -- Create an index number ordered by time.
AS [Sequence],
* from AgentInteractions
)
SELECT *,
ISNULL(DATEDIFF(Minute,
(SELECT other.TimeStamp
FROM AgentActions Other
WHERE other.Sequence = AgentActions.Sequence - 1 ),
AgentActions.TimeStamp),
0)
AS MinutesFromLastPoint
FROM AgentActions;
这是设置表
CREATE TABLE AgentInteractions
(
[Event] VARCHAR(12) NOT NULL,
[Timestamp] [DateTime] NOT NULL
);
INSERT INTO dbo.AgentInteractions( Event, TimeStamp )
VALUES ( 'Alpha', '1-Jan-2018 3:04:22 PM' ),
( 'Omega', '3-Jan-2018 10:04:22 PM' ),
( 'Beta', '2-Jan-2018 2:04:22 AM' );
结果
答案 3 :(得分:0)
据我了解,您需要更新持续时间列。
您可以使用以下内容:
update mytable a set duration = DateDiff( a.timestamp, select top b.timestamp from mytable b order by b.timestamp asc)
我无法测试它,只是为了给你一个想法(它可能有一些语法错误)。 使用'top'和'order by'子句应该可以解决问题。
(编辑)的
答案 4 :(得分:0)
我认为你最好创建一个触发器
CREATE TRIGGER update_duration ON sometable
INSTEAD OF INSERT
AS
DECLARE @lastDT datetime
BEGIN
SET @lastDT =
(SELECT TOP 1 _timestamp
FROM sometable
ORDER BY _timestamp DESC)
UPDATE sometable
SET duration = DATEDIFF(MINUTE, @lastDT, GETDATE())
END
答案 5 :(得分:0)
WITH rows AS
(
SELECT *, ROW_NUMBER() OVER (ORDER BY Col1) AS rn
FROM dbo.Table_2
)
SELECT mc.col1, DATEDIFF(HOUR, mc.Col1, mp.Col1) as TimeDiffInHours
FROM rows mc
JOIN rows mp
ON mc.rn = mp.rn-1