将时间戳不同的两行数据匹配成一行(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所有不正确的记录。然后我们将两个结果加入以毫秒为单位的时差。