复制存在日期间隔的最新日期的行值

时间:2019-08-17 22:11:17

标签: sql sql-server-2016

我正在Tableau中为一个新产品创建一个报告,该报告将捕获指标,例如先前的应用程序未决,新应用程序的一天结束等。为此,我需要每个应用程序的一天结束状态的快照每天。做出了高于我的薪资等级的决定,只捕获了滚动的7天数据增量。因此,发生的事情是在过去7天中没有状态更改的应用程序停止出现在数据库中,直到出现新的情况为止,这会导致日期之间出现间隔并在报告中遗漏我的号码。我需要的是每个应用程序每一天的快照,因此,当存在日期间隔时,我想获取前一天的最新记录并插入以填补两个日期之间的间隔。另外,我加入了信用评分表,有时我们将所有三个局都拉了,有时是两个,有时是一个,所以每天每个申请最多可以有三行。

我在该站点上查找了类似的问题,这些问题似乎有些相似,但是没有一个与我要完成的任务完全匹配,老实说,我不知道从哪里开始。相关子查询是否可以满足我的需求?我在下面提供了一些代码来显示当前数据。

drop table if exists #date
drop table if exists #test

create table #date
    (
        calendar_date date
    )

insert into #date
values
('2019-08-07'),
('2019-08-08'),
('2019-08-09'),
('2019-08-10'),
('2019-08-11'),
('2019-08-12')

create table #test
    (
        id int,
        period_date date,
        decision_status varchar(20),
        credit_score int,
        expired_flag bit
    )

insert into #test (id,period_date,decision_status,credit_score,expired_flag)
values
(1,'2019-08-08','declined',635,null),
(1,'2019-08-08','declined',642,null),
(1,'2019-08-09','declined',635,null),
(1,'2019-08-09','declined',642,null),
(1,'2019-08-10','declined',635,null),
(1,'2019-08-10','declined',642,null),
(1,'2019-08-11','declined',635,null),
(1,'2019-08-11','declined',642,null),
(1,'2019-08-12','declined',635,null),
(1,'2019-08-12','declined',642,null),
(2,'2019-08-08','review',656,null),
(2,'2019-08-08','review',648,null),
(2,'2019-08-09','review',656,null),
(2,'2019-08-09','review',648,null),
(2,'2019-08-12','review',656,null),
(2,'2019-08-12','review',648,null),
(3,'2019-08-08','preapproved',678,null),
(3,'2019-08-08','preapproved',689,null),
(3,'2019-08-08','preapproved',693,null),
(3,'2019-08-09','preapproved',678,null),
(3,'2019-08-09','preapproved',689,null),
(3,'2019-08-09','preapproved',693,null),
(3,'2019-08-11','preapproved',678,1),
(3,'2019-08-11','preapproved',689,1),
(3,'2019-08-11','preapproved',693,1),
(3,'2019-08-12','preapproved',678,1),
(3,'2019-08-12','preapproved',689,1),
(3,'2019-08-12','preapproved',693,1),
(4,'2019-08-08','onboarded',725,null),
(4,'2019-08-09','onboarded',725,null),
(4,'2019-08-10','onboarded',725,null),
(5,'2019-08-08','approved',685,null),
(5,'2019-08-08','approved',675,null),
(5,'2019-08-09','approved',685,null),
(5,'2019-08-09','approved',675,null),
(5,'2019-08-12','approved',685,1),
(5,'2019-08-12','approved',675,1)

查询:

select id, calendar_date, period_date, decision_status, credit_score, expired_flag
from #date join
     #test
     on calendar_date=dateadd(day,-1,period_date)
order by id, calendar_date

我只需要每天显示每个应用程序即可。

2 个答案:

答案 0 :(得分:0)

您可能只需要left join:只需要left join

select t.id, d.calendar_date, t.period_date, t.decision_status, t.credit_score, t.expired_flag
from #date d left join
     #test t
     on d.calendar_date = dateadd(day, -1, t.period_date)
order by id, d.calendar_date;

如果“应用程序”是指id中的#test,则使用cross join生成行,并使用outer apply填写值:

select t.id, d.calendar_date, t.period_date, t.decision_status, t.credit_score, t.expired_flag
from #date d cross join
     (select distinct id from #test) i outer apply
     (select top (1) t.*
      from #test t
      where t.id = i.id and t.date <= d.date
      order by t.date desc
     ) t

答案 1 :(得分:0)

更新: 在收到Gordon的答复后,这给了我一些启发,使我朝正确的方向前进,并进行了一些附加研究,我似乎找到了一种可行的解决方案。如果有人遇到此问题,我想在这里分享解决方案。我在下面发布代码:

drop table if exists #date
drop table if exists #test
drop table if exists #test1
drop table if exists #row_num

create table #date
    (
        calendar_date date
    )

insert into #date
values
('2019-08-07'),
('2019-08-08'),
('2019-08-09'),
('2019-08-10'),
('2019-08-11')

create table #test
    (
        id int,
        period_date date,
        decision_status varchar(20),
        credit_score int,
        expired_flag bit
    )

insert into #test (id,period_date,decision_status,credit_score,expired_flag)
values
(1,'2019-08-08','declined',635,null),
(1,'2019-08-08','declined',642,null),
(1,'2019-08-09','declined',635,null),
(1,'2019-08-09','declined',642,null),
(1,'2019-08-10','declined',635,null),
(1,'2019-08-10','declined',642,null),
(1,'2019-08-11','declined',635,null),
(1,'2019-08-11','declined',642,null),
(1,'2019-08-12','declined',635,null),
(1,'2019-08-12','declined',642,null),
(2,'2019-08-08','review',656,null),
(2,'2019-08-08','review',648,null),
(2,'2019-08-09','review',656,null),
(2,'2019-08-09','review',648,null),
(2,'2019-08-12','review',656,null),
(2,'2019-08-12','review',648,null),
(3,'2019-08-08','preapproved',678,null),
(3,'2019-08-08','preapproved',689,null),
(3,'2019-08-08','preapproved',693,null),
(3,'2019-08-09','preapproved',678,null),
(3,'2019-08-09','preapproved',689,null),
(3,'2019-08-09','preapproved',693,null),
(3,'2019-08-11','preapproved',678,1),
(3,'2019-08-11','preapproved',689,1),
(3,'2019-08-11','preapproved',693,1),
(3,'2019-08-12','preapproved',678,1),
(3,'2019-08-12','preapproved',689,1),
(3,'2019-08-12','preapproved',693,1),
(4,'2019-08-08','onboarded',725,null),
(4,'2019-08-09','onboarded',725,null),
(4,'2019-08-10','onboarded',725,null),
(5,'2019-08-08','approved',685,null),
(5,'2019-08-08','approved',675,null),
(5,'2019-08-09','approved',685,null),
(5,'2019-08-09','approved',675,null),
(5,'2019-08-12','approved',685,1),
(5,'2019-08-12','approved',675,1)

select id,calendar_date,decision_status,credit_score,expired_flag
      ,ROW_NUMBER() over(partition by id,calendar_date order by calendar_date) as row_id
      ,cast(ROW_NUMBER() over(partition by id,calendar_date order by calendar_date) as char(1)) as row_num
into #test1
from #date
join #test
    on calendar_date=dateadd(day,-1,period_date)
order by id,calendar_date

create table #row_num
    (
        row_id int,
        row_num char(1)
    )

insert into #row_num
values
(1,'1'),
(2,'2'),
(3,'3')

select i.id 
       ,d.calendar_date
       ,coalesce(t.decision_status,t1.decision_status) as decision_status
       ,coalesce(t.credit_score,t1.credit_score) as credit_score
       ,coalesce(t.expired_flag,t1.expired_flag) as expired_flag
from #date d 
     cross join
     (select distinct id 
      from #test1 ) i
     cross join #row_num r 
     left join #test1 t
        on t.id=i.id
        and t.row_id=r.row_id
        and t.calendar_date=d.calendar_date
     join
     (select id,row_id,decision_status,credit_score,expired_flag
             ,calendar_date as start_date
             ,lead(calendar_date,1,dateadd(day,1,(select max(calendar_date) from #date)))
              over (partition by id,row_id order by calendar_date) as end_date
      from #test1
     ) t1
        on t1.id=i.id
        and t1.row_id=r.row_id
        and d.calendar_date>=t1.start_date
        and d.calendar_date<t1.end_date
order by i.id,d.calendar_date,r.row_id

这为我提供了我所需要的,每天每个应用程序的所有每日记录。