zoukankan      html  css  js  c++  java
  • [ Merge 拉链表] merge实现数据仓库历史拉链表

    create table dm_channel_acct(    --渠道账户开户表
    	cust_no         varchar(20),   --客户号
    	channel_account varchar(20),   --渠道账号
    	sing_org        varchar(10),   --开户机构
    	sing_date       varchar(10),   --开户日期
    	logout_date     varchar(10),   --销户日期
    	acct_status     varchar(1),    --账号状态
    	start_date      varchar(10),   --拉链开始日期
      end_date        varchar(10)    --拉链结束日期
    );
    
    
    
    create table ods_data(           --渠道账户开户表 数仓增量数据
    	cust_no         varchar(20),   --客户号
    	channel_account varchar(20),   --渠道账号
    	sing_org        varchar(10),   --开户机构
    	sing_date       varchar(10),   --开户日期
    	logout_date     varchar(10),   --销户日期
    	acct_status     varchar(1)    --账号状态
    );
    
    -- 放入原数据
    insert into dm_channel_acct (cust_no, channel_account, sing_org, sing_date, logout_date, acct_status, start_date, end_date)
           values('1001', '201', 'zfb', '5701', '2020-01-05', '', 'Y', '2020-01-05', '9999-12-31')
           ;
           
    insert into dm_channel_acct (cust_no, channel_account, sing_org, sing_date, logout_date, acct_status, start_date, end_date)
           values('1001', '202', 'jd', '5701', '2020-01-07', '', 'Y', '2020-01-07', '9999-12-31')
           ;
    
    --设置数仓增量数据
    insert into ods_data (cust_no, channel_account, sing_org, sing_date, logout_date, acct_status, start_date, end_date)
           values('1001', '201', 'zfb', '5701', '2020-01-05', '2020-01-15', 'N')
           ;
           
    insert into ods_data (cust_no, channel_account, sing_org, sing_date, logout_date, acct_status, start_date, end_date)
           values('1001', '202', 'jd', '5701', '2020-01-05', '', 'Y')
           ;
           
    insert into ods_data (cust_no, channel_account, sing_org, sing_date, logout_date, acct_status, start_date, end_date)
           values('1001', '202', 'cft', '5705', '2020-01-15', '', 'Y')
           ;
    
    insert into ods_data (cust_no, channel_account, sing_org, sing_date, logout_date, acct_status, start_date, end_date)
           values('1002', '204', 'jd', '5705', '2020-01-15', '', 'Y')
           ;
    
    insert into ods_data (cust_no, channel_account, sing_org, sing_date, logout_date, acct_status, start_date, end_date)
           values('1002', '201', 'jd', '5705', '2020-01-15', '', 'Y')
           ;
           
    --写出要更新的语句,即dm_channel_acct和ods_data不同的记录
    select 
           nvl(dm.cust_no, ods.cust_no) as cust_no
           ,nvl(dm.channel_account, ods.channel_account) as channel_account 
           ,nvl(dm.channel_type, ods.channel_type) as channel_type
           ,nvl(dm.sign_org, ods.sign_org) as sign_org
           ,nvl(dm.sign_date, ods.sign_date) as sign_date
           ,nvl(dm.logout_date, ods.logout_date) as logout_date
           ,nvl(dm.acct_status, ods.acct_status) as acct_status
           ,case when ods.channel_account is null then dm.start_date
                 else '2020-01-17' 
             end as start_date
            ,case when ods.channel_account is null then '2020-01-17' 
                  esle dm.end_date
              end as end_date       --ods表中有该表数据的结束日期
    from ods_data ods 
    full join dm_channel_acct dm 
           on ods.channel_account = dm.channel_account 
          and ods.cust_no = dm.cust_no 
          and ods.acct_status = dm.acct_status 
          and ods.channel_type = dm.channel_type 
    where dm.channel_account is null 
       or (ods.channel_account is null and ccim.end_date = '999-12-31')  
    ;
    
    
    --使用merge更新
    merge into dm_channel_acct a 
    using(
    			select 
    			       nvl(dm.cust_no, ods.cust_no) as cust_no
    			       ,nvl(dm.channel_account, ods.channel_account) as channel_account 
    			       ,nvl(dm.channel_type, ods.channel_type) as channel_type
    			       ,nvl(dm.sign_org, ods.sign_org) as sign_org
    			       ,nvl(dm.sign_date, ods.sign_date) as sign_date
    			       ,nvl(dm.logout_date, ods.logout_date) as logout_date
    			       ,nvl(dm.acct_status, ods.acct_status) as acct_status
    			       ,case when ods.channel_account is null then dm.start_date
    			             else '2020-01-17' 
    			         end as start_date
    			        ,case when ods.channel_account is null then '2020-01-17' 
    			              esle dm.end_date
    			          end as end_date       --ods表中有该表数据的结束日期
    			from ods_data ods 
    			full join dm_channel_acct dm 
    			       on ods.channel_account = dm.channel_account 
    			      and ods.cust_no = dm.cust_no 
    			      and ods.acct_status = dm.acct_status 
    			      and ods.channel_type = dm.channel_type 
    			where dm.channel_account is null 
    			   or (ods.channel_account is null and ccim.end_date = '999-12-31') 
    ) b 
    on (a.cust_no = b.cust_no and a.channel_account = b.channel_account and a.channel_type = b.channel_type and a.channel_status = b.channel_status) 
    when matched then 
         update 
            set a.acct_status = b.acct_status 
               ,logout_date = b.logout_date
               ,a.end_date = '2020-01-17'
    when not matched then 
         insert (cust_no, channel_account, channel_type, sign_org, sign_date, logout_date, acct_status, start_date, end_date)
       values (b.cust_no, b.channel_account, b.channel_type, b.sign_org, b.sign_date, b.logout_date, b.acct_status, b.start_date, b.end_date)
    ;
    

      

  • 相关阅读:
    直接插入排序
    安卓突击:隐式、显式Intent
    安卓突击:Android 动画有哪几种?
    安卓突击:ANR
    安卓突击:系统上安装了多种浏览器,能否指定某浏览器访问指定页面
    安卓突击:系统上安装了多种浏览器,能否指定某浏览器访问指定页面
    Android:BroadcastReceiver的基础知识
    安卓突击:service的基础知识
    安卓突击:数据存储方式
    Android突击:常用的五种布局
  • 原文地址:https://www.cnblogs.com/x-you/p/12206850.html
Copyright © 2011-2022 走看看