从其他地方获取到比较完整的行业分类信息,导入到MySQL数据库表gbt中,结构与数据情况如下图所示:
+------+------+------+------+------+-------------------------+-----------------------------------------------+ | id | c1 | c2 | c3 | c4 | name | description | +------+------+------+------+------+-------------------------+-----------------------------------------------+ | 1 | A | | | | 农、林、牧、渔业 | 本门类包括01~05大类 | | 2 | | 1 | | | 农业 | 指对各种农作物的种植 | | 3 | | | 11 | | 谷物种植 | 指以收获籽实为主,供人类食用的农作物的种 | | 4 | | | | | | 植,如稻谷、小麦、玉米等农作物的种植 | | 5 | | | | 111 | 稻谷种植 | | | 6 | | | | 112 | 小麦种植 | | | 7 | | | | 113 | 玉米种植 | | | 8 | | | | 119 | 其他谷物种植 | | | 9 | | | 12 | | 豆类、油料和薯类种植 | | | 10 | | | | 121 | 豆类种植 | | ...(省略一部分) | 87 | | | | 512 | 灌溉服务 | 指对农业生产灌溉系统的经营与管理 | | 88 | | | | 513 | 农产品初加工服务 | 指对各种农产品(包括天然橡胶、纺织纤维原 | | 89 | | | | | | 料)进行脱水、凝固、去籽、净化、分类、晒干 | | 90 | | | | | | 、剥皮、初烤、沤软或大批包装以提供初级市场 | | 91 | | | | | | 的服务,以及其他农产品的初加工;其中棉花等 | | 92 | | | | | | 纺织纤维原料加工指对棉纤维、短绒剥离后的棉 | | 93 | | | | | | 籽以及棉花秸秆、铃壳等副产品的综合加工和利 | | 94 | | | | | | 用活动 | | 95 | | | | 519 | 其他农业服务 | 指防止病虫害的活动,以及其他未列明的农业 | | 96 | | | | | | 服务 | | 97 | | | 52 | | 林业服务业 | 指为林业生产服务的病虫害的防治、林地防火 | | 98 | | | | | | 等各种辅助性活动 | ...(省略一部分) | 2672 | | | | 7296 | 担保服务 | 指保证人和债权人约定,当债务人不履行债务 | | 2673 | | | | | | 时,保证人按照约定履行债务或者承担责任的行 | | 2674 | | | | | | 为活动;本类别特指专业担保机构的活动 | | 2675 | | | | 7299 | 其他未列明商务服务业 | 指上述未列明的商务、代理等活动 | | 2676 | T | | | | 国际组织 | 本门类包括96大类 | | 2677 | | 96 | | | 国际组织 | | | 2678 | | | 960 | 9600 | 国际组织 | 指联合国和其他国际组织驻我国境内机构等的 | | 2679 | | | | | | 活动 | +------+------+------+------+------+-------------------------+-----------------------------------------------+
可以看到,行业分类被划分成4个层次,按照深度优先的规则顺序排列,id是连续、递增的序号。
不难发现这些数据中存在这样的问题:
有些记录没有4个层次分类c1,c2,c3,c4的内容,只有name或者description信息。也很容易判断,这些信息是紧邻的分类信息的补充内容,即原本应该一条记录的内容,被“换行”保存成了多条,如这里的多条:
| 88 | | | | 513 | 农产品初加工服务 | 指对各种农产品(包括天然橡胶、纺织纤维原 | | 89 | | | | | | 料)进行脱水、凝固、去籽、净化、分类、晒干 | | 90 | | | | | | 、剥皮、初烤、沤软或大批包装以提供初级市场 | | 91 | | | | | | 的服务,以及其他农产品的初加工;其中棉花等 | | 92 | | | | | | 纺织纤维原料加工指对棉纤维、短绒剥离后的棉 | | 93 | | | | | | 籽以及棉花秸秆、铃壳等副产品的综合加工和利 | | 94 | | | | | | 用活动 |
应该被保存为一条:
| 88 | | | | 513 | 农产品初加工服务 | 指对各种农产品(包括天然橡胶、纺织纤维原料)进行脱水、凝固、去籽、净化、分类、晒干、剥皮、初烤、沤软或大批包装以提供初级市场的服务,以及其他农产品的初加工;其中棉花等纺织纤维原料加工指对棉纤维、短绒剥离后的棉籽以及棉花秸秆、铃壳等副产品的综合加工和利用活动 |
其他编号89-94的记录应删除。
使用SQL实现如上需求,如何实现?
分析上面的场景,需要处理的记录具有这样的特征:
- c1,c2,c3,c4字段都为空的记录最终需要被删除;
- 这些要被删除的记录,编号连续的,编为一组;
- 这些记录,应按照id从小到大顺序,将name和description添加到邻近的(较小id的)具有层级信息的记录的name和description上;
筛选出这些要删除的记录,可以使用c1=” and c2=” and c3=” and c4=”,但是由于每个字段可能有前后空格,每个字段进行trim的话稍显繁琐。
简单一点可以如下处理:trim(concat(c1,c2,c3,c4))=”。
将连续编号的记录化归到一组,有点熟悉,想起了这个有趣的查询。可以参考它的实现。
而分组后就可以将这些字段的name,description拼接起来了,注意拼接的顺序是按照id升序。MySQL中可以使用group_concat(… order by …)。而每个分组的min(id)-1就是我们要添加到的那条记录。
综合以上考虑,我们可以在一个SQL中实现添加到上一条记录的需求:
update gbt t1, ( select id-num as groupno ,min(id)-1 as target_id ,group_concat( trim(name) ORDER BY id SEPARATOR '' ) as name_to_append ,group_concat( trim(description) ORDER BY id SEPARATOR '' ) as description_to_append from ( select t1.*,@num:=@num+1 as num from gbt t1,(select @num:=1) t2 where trim (concat(c1,c2,c3,c4))='' order by id ) A group by id-num ) t2 set t1.name = concat(trim(t1.name),t2.name_to_append), t1.description = concat(trim (t1.description),t2.description_to_append) where t1.id = t2.target_id ;
当然,最后不要忘了删除这些额外的记录:
delete from gbt where trim(concat(c1,c2,c3,c4))='';
The post 将包含额外信息的连续记录添加到上一条记录中 appeared first on SQLParty.