将时间戳不同的两行数据匹配成一行(SQL服务器)
Match data of two rows with different timestamp, into one row (SQL Server)
我遇到了 SQL 服务器查询的问题。
您可以在下面的屏幕截图中看到我的数据库中的数据示例。包含作为属性的大数值的行实际上是卡片 reader 读取的票证事件。
还有一些行包含像 Eticket result
这样的字符串作为属性。当工单无效时产生该事件,系统会显示工单无效的原因。
我想要做的是创建一个新列(命名为 "reason"),它将包含所有类似于 'Eticket Result' 的属性。问题是所有这些包含 'ETICKET Result' 的属性都必须与正确的票号相匹配。原因属性与无效工单时间戳的时间差,不会超过500毫秒。
为了让它更容易理解,我在下面给你另一个我想做的截图。
这可以做到吗?我已经尝试了几个小时,但创建的脚本没有生成正确的结果。如果对您有帮助,我会在下面给出我所做的但未显示正确数据的查询。
DECLARE @alarm_table TABLE (
/*1*/server_timestamp DATETIME ,
/*2*/museum VARCHAR(255),
/*3*/turnstile VARCHAR(255),
/*4*/entrance VARCHAR(255),
/*5*/cardnumber VARCHAR(255),
/*6*/result VARCHAR(255),
/*7*/reason VARCHAR(255),
/*8*/attributes VARCHAR(255)
);
INSERT INTO @alarm_table
SELECT
/*1*/servertimestamp,
/*2*/hostname,
/*3*/substring([hostname], PatIndex('%[0-9]%', [hostname]), len([hostname])),
/*4*/substring(attributes, 31, 39),
/*5*/attributes,
/*6*/'NOT OK',
/*7*/'',
/*8*/attributes--substring(attributes, 70, 30)
FROM
eventlog el
where
(el.servertimestamp BETWEEN '8/24/2018' AND DATEADD(dd, +1, '8/27/2019'))
and (attributes like '%ticket %' and attributes like '%eticketing%' )
and hostname <> 'tapaeos'
order by
el.timestamp
UPDATE @alarm_table
SET cardnumber = substring(attributes, 31, 39)
UPDATE @alarm_table
SET result = case
when
(attributes like '%ticket 8%'
or attributes like '%ticket 9%'
or attributes like '%ticket 10%'
or attributes like '%ticket 11%'
or attributes like '%ticket 12%'
or attributes like '%ticket 13%'
or attributes like '%ticket 14%'
or attributes like '%knossos ticket 5%'
or attributes like '%knossos ticket 6%'
or attributes like '%knossos ticket 7%'
or attributes like '%klitys ticket 5%'
or attributes like '%klitys ticket 6%'
or attributes like '%klitys ticket 7%'
or attributes like '%olympieio ticket 5%'
or attributes like '%olympieio ticket 6%'
or attributes like '%olympieio ticket 7%'
)
then 'NOT OK'
else 'OK'
end
UPDATE @alarm_table
SET reason = case
when result = 'NOT OK' then
(SELECT top 1 attributes
FROM eventlog
WHERE DATEDIFF(second,servertimestamp,server_timestamp)<=1)
else ' '
end
UPDATE @alarm_table
SET museum = case
when museum like '%olymp%' then 'Olympieio'
when museum like '%knoss%' then 'Knossos'
when museum like '%sslope%' then 'Klitys'
when museum like '%acrop%' then 'Acropolis'
end
select
server_timestamp,
museum,
turnstile,
cardnumber,
result,
reason
-- attributes
from
@alarm_table
order by server_timestamp desc
非常感谢您的帮助,感谢您抽出宝贵时间。
试试这个:
select e1.*, e2.attributes reason
from (
select *
from eventlog
where charindex('ETICKET Result', attributes) = 0
) e1 left join (
select timestamp, attributes
from eventlog
where charindex('ETICKET Result', attributes) > 0
) e2 on abs(datediff(millisecond, e1.timestamp, e2.timestamp)) <= 500
在e1
中我们查询所有正确的记录(没有ETICKET Reason
),在e2
中我们select所有不正确的记录。然后我们将两个结果加入以毫秒为单位的时差。
我遇到了 SQL 服务器查询的问题。
您可以在下面的屏幕截图中看到我的数据库中的数据示例。包含作为属性的大数值的行实际上是卡片 reader 读取的票证事件。
还有一些行包含像 Eticket result
这样的字符串作为属性。当工单无效时产生该事件,系统会显示工单无效的原因。
我想要做的是创建一个新列(命名为 "reason"),它将包含所有类似于 'Eticket Result' 的属性。问题是所有这些包含 'ETICKET Result' 的属性都必须与正确的票号相匹配。原因属性与无效工单时间戳的时间差,不会超过500毫秒。
为了让它更容易理解,我在下面给你另一个我想做的截图。
这可以做到吗?我已经尝试了几个小时,但创建的脚本没有生成正确的结果。如果对您有帮助,我会在下面给出我所做的但未显示正确数据的查询。
DECLARE @alarm_table TABLE (
/*1*/server_timestamp DATETIME ,
/*2*/museum VARCHAR(255),
/*3*/turnstile VARCHAR(255),
/*4*/entrance VARCHAR(255),
/*5*/cardnumber VARCHAR(255),
/*6*/result VARCHAR(255),
/*7*/reason VARCHAR(255),
/*8*/attributes VARCHAR(255)
);
INSERT INTO @alarm_table
SELECT
/*1*/servertimestamp,
/*2*/hostname,
/*3*/substring([hostname], PatIndex('%[0-9]%', [hostname]), len([hostname])),
/*4*/substring(attributes, 31, 39),
/*5*/attributes,
/*6*/'NOT OK',
/*7*/'',
/*8*/attributes--substring(attributes, 70, 30)
FROM
eventlog el
where
(el.servertimestamp BETWEEN '8/24/2018' AND DATEADD(dd, +1, '8/27/2019'))
and (attributes like '%ticket %' and attributes like '%eticketing%' )
and hostname <> 'tapaeos'
order by
el.timestamp
UPDATE @alarm_table
SET cardnumber = substring(attributes, 31, 39)
UPDATE @alarm_table
SET result = case
when
(attributes like '%ticket 8%'
or attributes like '%ticket 9%'
or attributes like '%ticket 10%'
or attributes like '%ticket 11%'
or attributes like '%ticket 12%'
or attributes like '%ticket 13%'
or attributes like '%ticket 14%'
or attributes like '%knossos ticket 5%'
or attributes like '%knossos ticket 6%'
or attributes like '%knossos ticket 7%'
or attributes like '%klitys ticket 5%'
or attributes like '%klitys ticket 6%'
or attributes like '%klitys ticket 7%'
or attributes like '%olympieio ticket 5%'
or attributes like '%olympieio ticket 6%'
or attributes like '%olympieio ticket 7%'
)
then 'NOT OK'
else 'OK'
end
UPDATE @alarm_table
SET reason = case
when result = 'NOT OK' then
(SELECT top 1 attributes
FROM eventlog
WHERE DATEDIFF(second,servertimestamp,server_timestamp)<=1)
else ' '
end
UPDATE @alarm_table
SET museum = case
when museum like '%olymp%' then 'Olympieio'
when museum like '%knoss%' then 'Knossos'
when museum like '%sslope%' then 'Klitys'
when museum like '%acrop%' then 'Acropolis'
end
select
server_timestamp,
museum,
turnstile,
cardnumber,
result,
reason
-- attributes
from
@alarm_table
order by server_timestamp desc
非常感谢您的帮助,感谢您抽出宝贵时间。
试试这个:
select e1.*, e2.attributes reason
from (
select *
from eventlog
where charindex('ETICKET Result', attributes) = 0
) e1 left join (
select timestamp, attributes
from eventlog
where charindex('ETICKET Result', attributes) > 0
) e2 on abs(datediff(millisecond, e1.timestamp, e2.timestamp)) <= 500
在e1
中我们查询所有正确的记录(没有ETICKET Reason
),在e2
中我们select所有不正确的记录。然后我们将两个结果加入以毫秒为单位的时差。