前言
日常工作中,会处理很多数据,有时候会遇到这么一个情况,excel中收集的数据,标注了姓名,身份证号,户主姓名,与户主关系。因为可能存在户主姓名重名的情况,所以需要关联出户主身份证号。当我们找到数据提供人告诉他这个不知道怎么提取的时候,他会告诉你 “这同一户的数据是挨着的啊,你提取一下就行了。”
这种情况,一定让你十分的头痛,今天,我介绍几种我平时遇到的几种情况,以及我的处理方法。
数据相对规范
如果,表格内的数据相对规范,比如,同一户的数据挨在一起,并且户主的数据在一户里的第一个
姓名 | 身份证号 | 户主姓名 | 与户主关系 |
---|---|---|---|
AA | xxxxxxxxxxxxxxxxxx | AA | 户主 |
BB | xxxxxxxxxxxxxxxxxx | AA | 长子 |
这种格式的数据,直接在excel里边使用公式就能处理
A | B | C | D | E |
---|---|---|---|---|
姓名 | 身份证号 | 户主姓名 | 与户主关系 | 户主身份证号 |
AA | xxxxxxxxxxxxxxxxxx | AA | 户主 | =if(D2=“户主”,B2,E1) |
BB | xxxxxxxxxxxxxxxxxx | AA | 长子 |
将上面的公式根据自己情况修改一下,然后填充这一列,就能完成户主证件号的提取了
数据不太规范
有时候,数据并不是特别的规范,例如,虽然同一户的数据是挨在一起的,但是户主并不是第一个,可能是最后一个,或者在中间,遇到这种情况,我都是在数据库里处理的,excel可能可以处理,但是我并不擅长使用excel
姓名 | 身份证号 | 户主姓名 | 与户主关系 |
---|---|---|---|
AA | xxxxxxxxxxxxxxxxxx | CC | 长子 |
BB | xxxxxxxxxxxxxxxxxx | CC | 次子 |
CC | xxxxxxxxxxxxxxxxxx | CC | 户主 |
DD | xxxxxxxxxxxxxxxxxx | CC | 配偶 |
处理这种数据,首先,是要将数据规范化,将户主的数据排在前面,这时候,需要加入一个序号列,记录数据原来在excel中的位置
首先,我们将数据规范化
select * from tab order by 户主姓名,(case when 与户主关系 = '户主' then 0 else 1 end),序号
以上代码的写法,oracle和mysql都可以使用
mysql可以用if函数来简化case when
oracle可以用decode函数来简化
数据规范化之后,可以选择将规范后的数据放入excel中使用上面提到的方法处理,也可以在数据库中继续处理
mysql中处理起来相对容易
select t1.*,if(t1.与户主关系='户主',@id_card:=身份证号,@id_card) 户主证件号 from
(select * from tab order by 户主姓名,(case when 与户主关系 = '户主' then 0 else 1 end),序号) t1,(select @id_card:='') pm
oracle中处理起来,比mysql要复杂一点,因为在oracle中,并不能在查询语句中定义变量,需要写脚本才行
declare
ID_CARD varchar2(20);
begin
--写一个循环,遍历排序好的结果
for r in (select * from tab order by 户主姓名,(case when 与户主关系 = '户主' then 0 else 1 end),序号) loop
if(r.与户主关系='户主') then
ID_CARD:=r.身份证号;
end if;
update tab set 户主身份证号 = ID_CARD where 序号 = r.序号;
end loop;
commit; --循环结束后再提交,有助于提升效率,如果数据量太大的话,提升效率需要在循环内判断更新了多少次,分批次提交
end;