如何修复不完整的数据/日志

时间:2018-11-15 18:29:59

标签: sql-server

我有一个消息日志表,按日期排序,如下所示:

    Id      Name      Date                Type            Text
    --------------------------------------------------------------
    1       Vasya     2018/05/01 08:00    In              NULL
    2       Vasya     2018/05/01 09:00    Message         Hello
    3       Vasya     2018/05/01 18:00    Out             NULL
    4       Petya     2018/05/02 08:00    In              NULL
----- missing part (with message of type In)
    5       Vasya     2018/05/02 15:00    Message         Hello
    6       Vasya     2018/05/02 18:00    Out             NULL
    7       Petya     2018/05/02 18:10    Message         Good bye
    8       Petya     2018/05/02 19:00    Out             NULL
----- missing part (with message of type In)
    9       Masha     2018/05/03 09:00    Out             NULL
----- missing part (with message of type In)
    10      Ivan      2018/05/03 10:00    Hi              NULL
----- missing part (with message of type Out)

他们可以发送这样一个损坏的日志,我需要通过在缺少每个用户时为每个用户添加相应的In / Out消息来进行修复。

从下往上看:

  1. 如果某个用户的Out消息在日志中较早的位置(按日期)没有对应的In消息,则需要在日志顶部添加一个。 例如:N9出-> N0(日期)从顶端进入。

我可以通过使用每个用户的NOT EXISTS()来查找任何地方没有In消息的Out消息来做到这一点。

  1. 如果有第一个Out消息,并且较早的地方还有第二个Out,我需要在第二个Out消息之后添加In消息 示例:N6输出-> N3之后输入

在这个地方,我现在意识到我需要将JOIN Out消息加入到相应的OUT消息中,从而变得更早...

  1. 对于每个类型为NULL的消息,请添加换行输入/输出(实际上可以跳过输出)

谢谢

斯拉瓦

1 个答案:

答案 0 :(得分:0)

要查找缺少的Ins for Outs,例如:

;with Ins (Id, Name, Date, Type, Text)
as
(
select l.Id, l.Name, plm.Date, plm.Type, l.Text
from Log as l
   outer apply (select top 1 pl.Date, pl.Type
                from Log as pl 
                where pl.Type in ('In', 'Out') 
                      and pl.User = l.User
                      and pl.Date < l.Date
                order by pl.Date desc) as plm
where l.Type = 'Out'
)
insert into Log (Id, Name, Date, Type, Text)
select Id + 1, Name, 
     case 
       when Date is null 
       then '2000/01/01'
       else dateadd(second, -1, Date) -- make In a second earlier then Out
     end as NewDate,
     'In',
     Text
from Ins
where Type <> 'In'

看起来像只为消息找到丢失的Ins一样