不知道如何找到这个,这就是为什么我提前向社区道歉。
我在将一系列日志数据排序到用户的相应视图时遇到问题。
默认情况下,所有数据都以两种方式记录:插入时(操作= 1)和删除时(操作= 3)。
表日志包含以下列:旧,新,操作和日期。 在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 运行它,但仍然没有得到结果。 此外,没有循环是可能的。我需要获得一个查询,可以加入另一个查询。
正如我所看到的,在这里我需要检查由于操作类型和应用时间引起的范围。 可能有人有关于如何处理的建议吗? 非常感谢!
答案 0 :(得分: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