Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 将日志数据序列排序到用户的适当视图中(FIFO synonim)_Sql Server_Sql Server 2008_Tsql - Fatal编程技术网

Sql server 将日志数据序列排序到用户的适当视图中(FIFO synonim)

Sql server 将日志数据序列排序到用户的适当视图中(FIFO synonim),sql-server,sql-server-2008,tsql,Sql Server,Sql Server 2008,Tsql,我不知道如何找到这个,这就是我提前向社区道歉的原因 我在将日志数据序列排序到用户的适当视图中时遇到问题 默认情况下,所有数据都以两种方式记录:插入时(操作=1)和删除时(操作=3) 表日志有以下列:旧、新、操作和日期。 插入时,old列为空,new列获取一个值。在删除时,old列获取一个值,new列为空 您可以在示例代码中看到这一点 ;with x as (select null old, 'A' new, 1 operation, cast('20130822 12:00:01.100' a

我不知道如何找到这个,这就是我提前向社区道歉的原因

我在将日志数据序列排序到用户的适当视图中时遇到问题

默认情况下,所有数据都以两种方式记录:插入时(操作=1)和删除时(操作=3)

表日志有以下列:旧、新、操作和日期。 插入时,old列为空,new列获取一个值。在删除时,old列获取一个值,new列为空

您可以在示例代码中看到这一点

 ;with x as (select null old, 'A' new, 1 operation, cast('20130822 12:00:01.100' as datetime) dt
         union all 
         select null,'B', 1 , '20130822 12:00:01.700' dt
         union all
         select 'B',null, 3 , '20130822 12:00:02.100' dt
         union all
         select null,'C', 1 , '20130822 12:00:05.700' dt
         union all
         select 'C',null, 3 , '20130822 12:00:06.100' dt
         union all 
         select null,'B', 1 , '20130822 12:00:08.700' dt
         )
我需要得到的结果应该如下所示:

OLD     NEW      TIME
        A        22-08-2013 12:00:01
A|      A|B      22-08-2013 12:00:01
A|B     A|B|C    22-08-2013 12:00:02
A|B|C   A|C      22-08-2013 12:00:05
A|C     A        22-08-2013 12:00:06
A       A|B      22-08-2013 12:00:08
我试图通过for xml path运行这个,但仍然没有得到结果。 此外,不可能有循环。我需要得到一个查询,可以连接到另一个查询

如我所见,这里我需要检查由于操作类型和应用时间而产生的范围。 也许有人对如何处理这个问题有什么建议?
非常感谢

这个查询并不容易,但它是有效的

;with x(old, new, operation, dt) as (
    select null, 'A',  1, cast('20130822 12:00:01.100' as datetime) union all
    select null, 'B',  1, '20130822 12:00:01.700' dt union all
    select 'B',  null, 3, '20130822 12:00:02.100' dt union all
    select null, 'C',  1, '20130822 12:00:05.700' dt union all
    select 'C',  null, 3, '20130822 12:00:06.100' dt union all
    select null, 'B',  1, '20130822 12:00:08.700' dt
), y as (
    select x1.dt, isnull(x2.new, x2.old) u
    from x x1
    inner join x x2 on x1.dt >= x2.dt
    group by x1.dt, isnull(x2.new, x2.old)
    having sum((x2.operation - 2) * (-1)) > 0
)

select min(case i when 1 then new end) old
    , min(case i when 0 then new end) new
    , min(case i when 0 then dt end) dt
from (
    select distinct dt
        , dense_rank() over(order by dt) num
        , stuff ( (
            select '|' + u
            from y y2
            where y1.dt = y2.dt
            for xml path('')
        ), 1, 1, '') new
    from y y1
) t
cross join (values(0),(1))i(i)
group by num+i
having min(case i when 0 then dt end) is not null
order by dt

也许有可能以某种方式优化这个查询,因为当我用x as()替换第一条语句到我的实际数据查询(从一个包含100多亿条日志记录的表,再加上其他许多记录的表)时,我得到了21秒的执行时间。当我看到IO统计数据时,我震惊了,因为我的日志和其他表格上有20亿次逻辑读取。然而,当我将数据放到temp表(类似于@tmp)时,它工作正常且勤奋。不知何故,with操作符的行为不像@tmp表。可以做些什么来优化呢?哦,最后将操作字段返回到查询时出现问题…要获取操作字段,只需将
x1.操作
添加到select和group by parts中的y cte中。然后将此字段添加到最终查询中:
选择distinct dt,operation
min(案例i为0,然后操作结束)operation
谢谢!但是你觉得我提到的计划怎么样?我可以避免使用tmp表吗?你能解释一下你选择了什么算法来解决这个问题吗?为什么需要使用序列值Null复制值?