我有一个名为events
的表,看起来像这样:
timestamp | intvalue | hostname | attributes
2019-03-13 14:43:05.437| 257 | room04 | Success 000
2019-03-13 14:43:05.317| 257 | room03 | Success 000
2019-03-13 14:43:03.450| 2049 | room05 | Error 108
2019-03-13 14:43:03.393| 0 | room05 | TicketNumber=3
2019-03-13 14:43:02.347| 0 | room04 | TicketNumber=2
2019-03-13 14:43:02.257| 0 | room03 | TicketNumber=1
以上是包含数千行的表的示例。我将用几句话解释你在这张表中看到的内容。 timestamp
列给出了每个事件发生的日期和时间。在intvalue
专栏中,257
意味着成功进入,2049
意味着错误,而0
意味着要求提供机票。 hostname
给出了读取每张票的卡/票读取器的名称,而attributes
列给出了一些细节,如票号(1,2,3等)或错误类型(即108或109)以及是否事件成功。
在这种情况下,有一种模式表明,如果票证请求进入并且它有效并且发生在像14:43:02.257
这样的时间,则成功输入的消息将在6秒内写入数据库(作为新事件)票证阅读器读取票证后最多(即14:49:02.257最大值)。
如果故障单无法进入,则在100 ms的时间限制之后,将在数据库中写入错误消息。
所以在这个例子中我想要做的是创建一个如下所示的表
timestamp | intvalue | hostname | result | ticketnumber
2019-03-13 14:43:05.437| 257 | room04 | Success 000 | TicketNumber=2
2019-03-13 14:43:05.317| 257 | room03 | Success 000 | TicketNumber=1
2019-03-13 14:43:03.450| 2049 | room05 | Error 108 | TicketNumber=3
正如您所看到的,TicketNumber=3
的票证与结果Error 108
相匹配,因为如果您查看初始表格,他们的时间幅度小于100毫秒,其他两张票证与他们各自的结果一对一匹配,因为时间间隔小于6秒(超过100毫秒)。您还可以注意到,主机名可以帮助匹配,具有TicketNumber=3
属性的行具有hostname
的room05
,就像具有Error 108
属性的下一行一样。
我一直试图自己加入这张桌子或加入CTE。我已经使用了交叉应用,我也尝试了使用datediff
的方法,但我失败了,我被困住了。有没有人可以帮助我并向我展示一种达到预期结果的正确方法?非常感谢您的宝贵时间。
时间滞后似乎没有什么区别,除非某个单独的房间可以与成功和失败消息交错。假设两个请求没有发生在没有干预事件的行中,那么你可以使用lag()
:
select e.*
from (select timestamp, intvalue, hostname, attributes,
lag(attributes) over (partition by hostname order by timestamp) as ticketnumber
from event
) e
where intvalue > 0
order by timestamp
好的......这是您根据您提供的数据要求的结果。这只是如何编写自联接以获取示例中的结果的示例。我希望这会把你推向正确的方向。
IF OBJECT_ID('tempdb..#t') IS NOT NULL
BEGIN
DROP TABLE #t
END
CREATE TABLE #t
(
[timestamp] DATETIME,
intValue INT,
hostName VARCHAR(50),
attributes VARCHAR(50)
)
INSERT INTO #t([timestamp], intValue, hostName, attributes)
VALUES ('2019-03-13 14:43:05.437', 257, 'room04', 'Success 000'),
('2019-03-13 14:43:05.317',257, 'room03','Success 000'),
('2019-03-13 14:43:03.450',2049, 'room05','Error 108'),
('2019-03-13 14:43:03.393',0, 'room05','TicketNumber=3'),
('2019-03-13 14:43:02.347',0, 'room04','TicketNumber=2'),
('2019-03-13 14:43:02.257',0, 'room03','TicketNumber=1')
SELECT x.[timestamp], x.intValue, x.hostName, x.attributes result, y.attributes
ticketnumber
FROM (SELECT * FROM #t WHERE intValue > 0) AS x
INNER JOIN #t y
ON x.hostName = y.hostName AND y.intValue = 0
GROUP BY x.[timestamp], x.intValue, x.hostName, x.attributes, y.attributes
ORDER BY x.[timestamp] DESC
我不会尝试将其复制到您的项目中并使用它,这只是如何使用连接的示例。在发布完整的解决方案之前,我需要更多关于您想要完成的信息,因为有更好的方法来生成大型数据集的报告。 - 比尔
由于您使用的是SQL 2017,因此可以使用超前/滞后。
with evt(timestamp,intvalue,hostname,attributes) as
(
select cast('2019-03-13 14:43:05.437' as datetime), 257 , 'room04','Success 000' union all
select cast('2019-03-13 14:43:05.317' as datetime), 257 , 'room03','Success 000' union all
select cast('2019-03-13 14:43:03.450' as datetime), 2049 , 'room05','Error 108' union all
select cast('2019-03-13 14:43:03.393' as datetime), 0 , 'room05','TicketNumber=3' union all
select cast('2019-03-13 14:43:02.347' as datetime), 0 , 'room04','TicketNumber=2' union all
select cast('2019-03-13 14:43:02.257' as datetime), 0 , 'room03','TicketNumber=1'
)
select [timestamp], intvalue, hostname, attributes, lag(attributes) over (partition by hostname order by timestamp) ticketnumber, datediff(ss,lag([timestamp]) over (partition by hostname order by timestamp), [timestamp]) lapse
from evt
order by timestamp