使用以前的现有记录填写缺失记录

时间:2017-06-26 13:47:30

标签: sql-server

我有一个现有的数据库,前端应用程序会生成一些逻辑。 现在,我必须从该数据库中进行报告,并且我面临着记录丢失的问题,这些记录在前端以记录为基础,但在报告中存在问题 鉴于以下表格:

create table #T (id int, id1 int, label varchar(50))
create table #T1 (id int, T_id1 int, A int, B int, C int)

使用值:

insert into #T values (10, 1, 'label1'), (10, 2, 'label2'), (10, 3, 'label3'), (10, 15, 'label15'), (10, 16, 'label16'), (20, 100, 'label100'), (20, 101, 'label101')
insert into #T1 values (10, 1, 100, 200, 300), (10, 15, 150, 250, 350), (20, 100, 151, 251, 351), (20, 101, 151, 251, 351)

如果我发表报告,我们可以看到一些丢失的记录:

select #T.id, #T.id1, #T1.A, #T1.B, #T1.C
from    #T left join #T1 on #T.id1 = #T1.T_id1

结果:

id  id1 A   B   C
10  1   100 200 300
10  2   NULL    NULL    NULL
10  3   NULL    NULL    NULL
10  15  150 250 350
10  16  NULL    NULL    NULL
20  100 151 251 351
20  101 151 251 351

预期结果将是:

id  id1 A   B   B
10  1   100 200 300
10  2   100 200 300
10  3   100 200 300
10  15  150 250 350
10  16  150 250 350
20  100 151 251 351
20  101 151 251 351

正如您在此处所看到的,缺少的数据是从给定ID的第一个(在id,id1顺序中)之前的现有记录中填充的。对于给定的id,可以有任何数量的"缺失"记录和给定的id在不存在的记录之后可以有任意数量的现有记录。 我可以用光标做到这一点,但我正在寻找没有光标的解决方案

2 个答案:

答案 0 :(得分:2)

您可以使用子查询(查找具有相同值的组)+窗口函数

WITH Grouped AS (
    SELECT #T.id, #T.id1, #T1.A, #T1.B, #T1.C, 
        GroupN = SUM(CASE WHEN #T1.A IS NULL THEN 0 ELSE 1 END) OVER(/* PARTITION BY id ? */ ORDER BY id1 ROWS UNBOUNDED PRECEDING)
    FROM    #T 
    LEFT JOIN #T1 ON #T.id1 = #T1.T_id1
)
SELECT Grouped.id, Grouped.id1,
    A = MAX(A) OVER(PARTITION BY GroupN),
    B = MAX(B) OVER(PARTITION BY GroupN),
    C = MAX(C) OVER(PARTITION BY GroupN)
FROM Grouped

答案 1 :(得分:0)

您可以在sql下面使用所需的输出:

with cte (id, id1, A, B, C)
as
(
    select #T.id, #T.id1, #T1.A, #T1.B, #T1.C
    from    #T left join #T1 on #T.id1 = #T1.T_id1
)
select cte.id, cte.id1, 
coalesce(cte.A,TT.A) A,
coalesce(cte.B,TT.B) B,
coalesce(cte.C,TT.C) C
from cte
left join
(
    select p.id1,max(q.id1) id1_max
    from cte p
    inner join cte q on p.id1 > q.id1 and p.a is null and q.a is not null
    group by p.id1
) T on  cte.id1 = T.id1
left join cte TT on T.id1_max = TT.id1