-1

不知道如何找到这个,这就是为什么我提前向社区道歉。

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

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

表 Logs 具有以下列:旧、新、操作和日期。在 INSERT 上,列为 NULL,列得到一个值。在 DELETE 上,列得到一个值,列为 NULL。

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

 ;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运行它,但仍然没有得到结果。此外,没有循环是可能的。我需要得到一个查询,可以加入另一个查询。

如我所见,由于操作类型和应用时间,我需要在这里检查范围。可能有人对如何处理有建议?非常感谢!

4

1 回答 1

0

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

;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
于 2013-08-22T15:07:03.970 回答