SQL 当前表与历史表字段对比 两个表结构相同(在线等小弟只有20分了非常感谢)

xuyoubin1987 2013-09-04 10:57:04
有三个表A(当前表),B(历史表),C(对比表)A与B根据nameID和YM对比找出两表中不同的信息 然后把不同信息插入到表C中,
table A(当前表)YM和nameId为主键
YM(期次) name nameId adress
201309 张三 01 济南

table B(历史表) YM和nameId为主键

YM(期次) name nameId adress
201308 李四 01 泰安
A与B对比后不同信息如下表C
table C(对比表) YM,nameId,tbCode和fdCode为主键
YM(期次) nameId tbCode(变更字段所在表) fdCode(变更字段) last(变更前内容) end(变更后内容)
201309 01 A name 李四 张三
201309 01 A adress 泰安 济南


...全文
520 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
liuying_luck_leo 2014-06-11
  • 打赏
  • 举报
回复
楼主,对于多字段的你是怎么实现的呀?跪求示例
xuyoubin1987 2013-09-11
  • 打赏
  • 举报
回复
谢谢各位 我弄出来了
无敌小二傻 2013-09-09
  • 打赏
  • 举报
回复
用merge吧,很简单
xuyoubin1987 2013-09-04
  • 打赏
  • 举报
回复
引用 6 楼 HJ_daxian 的回复:
是以当前表为对照表吗 ?

with tableA as
(
     select '201309' ym,'张三' name,'01' nameid,'济南' adress from dual union all
     select '201309' ym,'丢丢' name,'02' nameid,'北京' adress from dual 
),tableB as
(
     select '201308' ym,'李四' name,'01' nameid,'南京' adress from dual union all
     select '201308' ym,'豆豆' name,'02' nameid,'北京' adress from dual 
)

select ym,nameid,'A' tbCode,'name' fdCode,n1 last,n2 end
from (
select a.nameid,a.ym,a.name n1,b.name n2
from tableA a left join tableB b on a.nameid = b.nameid
where a.name<>b.name )
union all
select ym,nameid,'A' tbCode,'adress' fdCode,a1 last,a2 end
from (
select a.nameid,a.ym,a.adress a1,b.adress a2
from tableA a left join tableB b on a.nameid = b.nameid
where a.adress<>b.adress)

     ym   nameid   tbCode  fdCode  last  end
-----------------------------------------------------------
1	201309	01	A	name	张三	李四
2	201309	02	A	name	丢丢	豆豆
3	201309	01	A	adress	济南	南京

是以当前表为对照 谢谢 高手
xuyoubin1987 2013-09-04
  • 打赏
  • 举报
回复
引用 5 楼 dyccsxg 的回复:
是 nameId 相同其他字段不同就计入C表?
对的 nameId 相同 就计入 C表
  • 打赏
  • 举报
回复
是以当前表为对照表吗 ?

with tableA as
(
     select '201309' ym,'张三' name,'01' nameid,'济南' adress from dual union all
     select '201309' ym,'丢丢' name,'02' nameid,'北京' adress from dual 
),tableB as
(
     select '201308' ym,'李四' name,'01' nameid,'南京' adress from dual union all
     select '201308' ym,'豆豆' name,'02' nameid,'北京' adress from dual 
)

select ym,nameid,'A' tbCode,'name' fdCode,n1 last,n2 end
from (
select a.nameid,a.ym,a.name n1,b.name n2
from tableA a left join tableB b on a.nameid = b.nameid
where a.name<>b.name )
union all
select ym,nameid,'A' tbCode,'adress' fdCode,a1 last,a2 end
from (
select a.nameid,a.ym,a.adress a1,b.adress a2
from tableA a left join tableB b on a.nameid = b.nameid
where a.adress<>b.adress)

     ym   nameid   tbCode  fdCode  last  end
-----------------------------------------------------------
1	201309	01	A	name	张三	李四
2	201309	02	A	name	丢丢	豆豆
3	201309	01	A	adress	济南	南京

dyccsxg 2013-09-04
  • 打赏
  • 举报
回复
是 nameId 相同其他字段不同就计入C表?
xuyoubin1987 2013-09-04
  • 打赏
  • 举报
回复
顶一下了 求帮忙啊
xuyoubin1987 2013-09-04
  • 打赏
  • 举报
回复
引用 2 楼 HJ_daxian 的回复:
左连接 判断值
怎么写啊?我SQL基础很差的 麻烦给写下吧 谢了
  • 打赏
  • 举报
回复
左连接 判断值
xuyoubin1987 2013-09-04
  • 打赏
  • 举报
回复
帮忙解决下吧 非常感谢
  • 打赏
  • 举报
回复
思路都差不多 因为每个字段变动 都会添加一条对比数据 如果闲麻烦 那可以写个存储 以字段数量来循环判断 有数据就插入 没有就跳过
xuyoubin1987 2013-09-04
  • 打赏
  • 举报
回复
引用 9 楼 HJ_daxian 的回复:
[quote=引用 8 楼 xuyoubin1987 的回复:] 是以当前表为对照 谢谢 高手
那就按照上面写的插入到表C就可以咯

insert into tableC

select ym,nameid,tbCode,fdCode,last,end
from
(
select ym,nameid,'A' tbCode,'name' fdCode,n1 last,n2 end
from (
select a.nameid,a.ym,a.name n1,b.name n2
from tableA a left join tableB b on a.nameid = b.nameid
where a.name<>b.name )
union all
select ym,nameid,'A' tbCode,'adress' fdCode,a1 last,a2 end
from (
select a.nameid,a.ym,a.adress a1,b.adress a2
from tableA a left join tableB b on a.nameid = b.nameid
where a.adress<>b.adress)
)
[/quote] 我要是一个表有三四十个字段那不要对比三四十次啊 ! SQL太大了吧?唉!!
xuyoubin1987 2013-09-04
  • 打赏
  • 举报
回复
引用 10 楼 dyccsxg 的回复:
再给个另一种方法:

create table A(ym int, name varchar2(12), nameId varchar2(10), address varchar2(100));
create table B(ym int, name varchar2(12), nameId varchar2(10), address varchar2(100));
create table C(
  ym int, nameId varchar2(10), tbCode varchar2(10), 
  fdCode varchar2(15), last varchar2(100), end varchar2(100)
);
  
insert into A(ym, name, nameId, address) values(201309, '张三', '01', '济南');
insert into B(ym, name, nameId, address) values(201309, '李四', '01', '泰安');

declare
  cursor c1 is
  select a.*, b.name b_name, b.address b_address 
  from A, B
  where a.nameId=b.nameId and a.ym=b.ym;
  v_sql varchar2(1024);
  v_sql_pre varchar2(100);
begin
  for c1_res in c1 loop
    v_sql_pre := 'insert into c(ym, nameId, tbCode, fdCode, last, end) values('||c1_res.ym||', '''||c1_res.nameId||''', ''A'', ';
    if c1_res.name != c1_res.b_name then 
      v_sql := v_sql_pre||'''name'', '''||c1_res.name||''', '''||c1_res.b_name||''')';
      execute immediate v_sql;
    end if;
    if c1_res.address != c1_res.b_address then 
      v_sql := v_sql_pre||'''address'', '''||c1_res.address||''', '''||c1_res.b_address||''')';
      execute immediate v_sql;
    end if;
  end loop;
end;
/

 
select * from c;
谢谢 刚才午休了一会 我看看哈
dyccsxg 2013-09-04
  • 打赏
  • 举报
回复
再给个另一种方法:

create table A(ym int, name varchar2(12), nameId varchar2(10), address varchar2(100));
create table B(ym int, name varchar2(12), nameId varchar2(10), address varchar2(100));
create table C(
  ym int, nameId varchar2(10), tbCode varchar2(10), 
  fdCode varchar2(15), last varchar2(100), end varchar2(100)
);
  
insert into A(ym, name, nameId, address) values(201309, '张三', '01', '济南');
insert into B(ym, name, nameId, address) values(201309, '李四', '01', '泰安');

declare
  cursor c1 is
  select a.*, b.name b_name, b.address b_address 
  from A, B
  where a.nameId=b.nameId and a.ym=b.ym;
  v_sql varchar2(1024);
  v_sql_pre varchar2(100);
begin
  for c1_res in c1 loop
    v_sql_pre := 'insert into c(ym, nameId, tbCode, fdCode, last, end) values('||c1_res.ym||', '''||c1_res.nameId||''', ''A'', ';
    if c1_res.name != c1_res.b_name then 
      v_sql := v_sql_pre||'''name'', '''||c1_res.name||''', '''||c1_res.b_name||''')';
      execute immediate v_sql;
    end if;
    if c1_res.address != c1_res.b_address then 
      v_sql := v_sql_pre||'''address'', '''||c1_res.address||''', '''||c1_res.b_address||''')';
      execute immediate v_sql;
    end if;
  end loop;
end;
/

select * from c;
  • 打赏
  • 举报
回复
引用 8 楼 xuyoubin1987 的回复:
是以当前表为对照 谢谢 高手
那就按照上面写的插入到表C就可以咯

insert into tableC

select ym,nameid,tbCode,fdCode,last,end
from
(
select ym,nameid,'A' tbCode,'name' fdCode,n1 last,n2 end
from (
select a.nameid,a.ym,a.name n1,b.name n2
from tableA a left join tableB b on a.nameid = b.nameid
where a.name<>b.name )
union all
select ym,nameid,'A' tbCode,'adress' fdCode,a1 last,a2 end
from (
select a.nameid,a.ym,a.adress a1,b.adress a2
from tableA a left join tableB b on a.nameid = b.nameid
where a.adress<>b.adress)
)

3,499

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 高级技术相关讨论专区
社区管理员
  • 高级技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧