如何创建SCD 2表的每日更改报告

时间:2012-06-16 07:01:39

标签: sql-server tsql data-warehouse scd2

我需要生成报告,该报告将显示SCD表每天新增/更改的行数。

这是创建表的SQL:

create table #scd(
  code      nvarchar not null
, startdate date     not null
, enddate   date
);
alter table #scd add constraint pk_scd primary key (code, startdate);


insert into #scd values
 ('A', '2012-06-01', '2012-06-02')
,('B', '2012-06-01', '2012-06-02')
,('A', '2012-06-02', '2012-06-03')
,('B', '2012-06-02', '2012-06-04')
,('A', '2012-06-03', '2012-06-04')
,('A', '2012-06-04', null)
,('B', '2012-06-04', null)
,('C', '2012-06-04', null)

select * from #scd

结果如下:

code    startdate   enddate
A   2012-06-01  2012-06-02
B   2012-06-01  2012-06-02
A   2012-06-02  2012-06-03
B   2012-06-02  2012-06-04
A   2012-06-03  2012-06-04
A   2012-06-04  NULL
B   2012-06-04  NULL
C   2012-06-04  NULL

现在,我需要制作这样的东西:

date            new changed
2012-06-01      2   0
2012-06-02      0   2
2012-06-03      0   1
2012-06-04      1   2

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

; with
q_00 as ( -- get new records
    select
          code 
        , startdate
    from #scd as s
    where s.startdate = (select MIN(xx.startdate) from #scd as xx where xx.code = s.code)
),
q_01 as ( -- get changed records, those that are not new
    select
          s.code 
        , s.startdate
    from #scd      as s
    left join q_00 as b on b.code = s.code and b.startdate = s.startdate
    where b.code is null
),
q_03 as ( -- get the list of all possible dates
    select distinct 
        startdate
    from #scd
),
q_04 as ( -- count new records per date
    select
          startdate
        , COUNT(1)  as new_rec
    from q_00
    group by startdate
),
q_05 as ( -- count changed records per date
    select
          startdate
        , COUNT(1)  as chn_rec
    from q_01
    group by startdate
)
select
      a.startdate          as OnDate
    , coalesce(new_rec, 0) as new_records
    , coalesce(chn_rec, 0) as changed_records
from      q_03 as a
left join q_04 as b on b.startdate = a.startdate
left join q_05 as c on c.startdate = a.startdate
order by  a.startdate
;

答案 1 :(得分:0)

获得结果的另一种方式

Select A.startdate,isnull(B.cnt,0) [new],(A.Cnt-isnull(B.cnt,0)) [changed]
from
(select startdate,COUNT(*) Cnt from #scd
group by startdate)A
left outer join
(select startdate,COUNT(*) cnt from #scd S1 where code not in
                     (select code from #scd S2 where S2.startdate<S1.startdate)
group by startdate)B
on A.startdate=B.startdate