`
yongguang423
  • 浏览: 110583 次
  • 性别: Icon_minigender_1
  • 来自: 山东
社区版块
存档分类
最新评论

使用PL/SQL合并重复的数据

 
阅读更多

假设有一张表oldyang_bayern,取其中的10条数据作为参考:
plsql1

现在需要合并此张表中姓名重复的数据,将符合条件的字段值,合并到重名数据中ID最高的那一条。

要合并的字段分为三种情况:

1. 常规字段(DEPARTMENT/JOBTITLE):取重名数据中ID最高的非空值,例如“施魏因施泰格”的DEPARTMENT字段合并后,应取值“组织部”;

2. 依据数值大小取值的字段(SALARY):取重名数据中的最大值;

3. 非常规字段(CITY/DITRICT/ADDRESS/ADDRESSRANK):这些字段都与地址相关,以ADDRESSRANK最高的那条数据为准(ADDRESSRANK由高到低分别为S|A|B|C|D),然后取此条数据中的CITY/DITRICT/ADDRESS值;如果ADDRESSRANK相同,取ID最高的数据。

依据以上条件,此前的10条数据合并后的结果应如下所示:
plsql2

我所给出的方法:

处理合并的存储过程prc_oldyang_bayern

create or replace procedure prc_oldyang_bayern(pname varchar2)
is
cursor cur is
 select * from oldyang_bayern
  where name=pname order by id desc; --NAME相同的数据按id降序排列

 

--申明记录表info_table,用于存放NAME相同的数据
 type info_table_type is table of oldyang_bayern%ROWTYPE index by binary_integer;
 info_table info_table_type;

 

 info_dest oldyang_bayern%rowtype;
 nCount number(2):=0; --计数变量
 vi number(2); --在更新地址字段时将会用于放入记录号

 

begin
 open cur;
  --通过循环计数的方式将重复的记录放入记录表
  loop
   nCount:= nCount+1;
   fetch cur into info_table(nCount);
   exit when cur%notfound;
  end loop;
 close cur;

 

 nCount := nCount - 1;

 

 --更新常规字段DEPARTMENT/JOBTITLE
 for i in 1..nCount-1 loop
  if i = 1 then
   info_dest.DEPARTMENT:= nvl(info_table(i).DEPARTMENT, info_table(i+1).DEPARTMENT);
  else
   info_dest.DEPARTMENT:= nvl(info_dest.DEPARTMENT, info_table(i+1).DEPARTMENT);
  end if;
 end loop;

 

 for i in 1..nCount-1 loop
  if i = 1 then
   info_dest.JOBTITLE:= nvl(info_table(i).JOBTITLE, info_table(i+1).JOBTITLE);
  else
   info_dest.JOBTITLE:= nvl(info_dest.JOBTITLE, info_table(i+1).JOBTITLE);
  end if;
 end loop;

 

 --更新SALARY字段
 for i in 1..nCount-1 loop
  if i = 1 then
   info_dest.SALARY:= greatest(nvl(info_table(i).SALARY,-1), nvl(info_table(i+1).SALARY,-1));
  else
   info_dest.SALARY:= greatest(nvl(info_dest.SALARY,-1), nvl(info_table(i+1).SALARY,-1));
  end if;
 end loop;
 info_dest.SALARY:= replace(info_dest.SALARY,-1); --处理当SALARY为空值时的状况

 

 --更新与ADDRESSRANK相关的字段
 --此处引用了一个自定义函数fun_get_ranknum
 --利用这个函数将地址等级S|A|B|C|D转换成对应的地址等级序号1|2|3|4|5(函数代码会在后面列出)
 --接着拼接地址等级序号+记录号,取拼接后最小值
 --此方法用于处理当ADDRESSRANK相同时,取ID最高的那条ADDRESSRANK相关记录
 --(注:在游标中记录已按ID降序排列)
 for i in 1..nCount-1 loop
  if i = 1 then
   info_dest.ADDRESSRANK:= least(fun_get_ranknum(info_table(i).ADDRESSRANK)||i, fun_get_ranknum(info_table(i+1).ADDRESSRANK)||i+1);
  else
   info_dest.ADDRESSRANK:= least(info_dest.ADDRESSRANK,  fun_get_ranknum(info_table(i+1).ADDRESSRANK)||i+1);
  end if;
 end loop;

 

 vi:= regexp_substr(info_dest.ADDRESSRANK, '\d$'); --使用正则表达式取出拼接值中的记录号
 info_dest.ADDRESSRANK:=info_table(vi).ADDRESSRANK;
 info_dest.CITY:=info_table(vi).CITY;
 info_dest.DISTRICT:=info_table(vi).DISTRICT;
 info_dest.ADDRESS:=info_table(vi).ADDRESS;

 

 --将筛选后的变量值更新到ID最高的记录当中
 update oldyang_bayern
   set DEPARTMENT=info_dest.DEPARTMENT,
     JOBTITLE=info_dest.JOBTITLE,
     SALARY=info_dest.SALARY,
     CITY=info_dest.CITY,
     DISTRICT=info_dest.DISTRICT,
     ADDRESS=info_dest.ADDRESS,
     ADDRESSRANK=info_dest.ADDRESSRANK
  where id = info_table(1).id;

 

 --删除重复的记录
 delete from oldyang_bayern where name=pname and id != info_table(1).id;

 

 commit;
end ;

 

存储过程中所用到的自定义函数fun_get_ranknum

create or replace function fun_get_ranknum(prank in varchar2)
return varchar2
is
 Result varchar(2);
 vcTemp varchar(2);
begin
 vcTemp:=prank;

 

 case
  when vcTemp = 'S' then
     vcTemp:= '1';
  when vcTemp = 'A' then
     vcTemp:= '2';
  when vcTemp = 'B' then
     vcTemp:= '3';
  when vcTemp = 'C' then
     vcTemp:= '4';
  when vcTemp = 'D' then
     vcTemp:= '5';
  when vcTemp is null then
     vcTemp:= '9';
 end case;

 

 Result := vcTemp;
 return(Result);

 

 exception
  when others then
   Result := '9';
  return result;
end ;

 

利用匿名块传递重复姓名到prc_oldyang_bayern,执行合并过程

declare
cursor cur is select name from oldyang_bayern group by name having count(*)>1;
rec cur%rowtype;
begin
 open cur;
  loop
   fetch cur into rec;
     exit when cur%notfound;
   prc_oldyang_bayern(rec.name);
  end loop;
 close cur;
end;

 转自:http://www.oldyang.com/2009/06/23/using_plsql_remove_duplicates/

分享到:
评论

相关推荐

    ORACLE PL/SQL从入门到精通

    PL/SQL变量的声明和使用是编程的基础,涉及到变量的声明、初始化、数据类型、%type属性等。变量的赋值和使用也是需要掌握的内容。 此外,书中还涉及到了ORACLE数据库的安装、存储过程的编写、序列操作、数据类型...

    sql and pl/sql

    ### SQL与PL/SQL知识点详解 #### 一、资料库基本概念 - **数据库管理系统(DBMS)**:Oracle数据库管理系统是一...- **使用SQL于PL/SQL中**:在PL/SQL中嵌入SQL语句。 - **控制流程语法规则**:如循环、条件判断等。

    Oracle PL/SQL常用47个工具包

    27. **DBMS_TYPES**: 定义自定义数据类型,扩展PL/SQL的数据模型。 28. **DBMS_REGISTRY**: 管理数据库注册,用于分布式数据库环境。 29. **DBMS_REPAIR**: 用于修复表和索引的损坏。 30. **DBMS_FLASHBACK**: ...

    oracle/SQL和PL/SQL课堂笔记

    Oracle SQL和PL/SQL是数据库管理和编程的重要工具,主要用于处理Oracle数据库中的数据。这篇课堂笔记主要涵盖了基础的SQL查询语法和部分PL/SQL概念。 首先,SQL查询的基础是从数据库中选择数据。`SELECT`语句用于...

    pl/sql开发

    PL/SQL是Oracle数据库系统中的过程化语言,它结合了SQL查询语言和程序设计元素,使得开发者能够编写复杂的数据库操作程序。以下是对PL/SQL开发的一些关键知识点的详细解释: 1. **基本查询与排序**: - **SELECT...

    PL/SQL Developer8用户指南

    - **保存SQL脚本**:讲解如何将SQL查询保存为脚本,方便以后重复使用。 - **创建标准查询**:解释如何创建可复用的标准查询模板。 #### 七、命令窗口(The Command Window) - **输入SQL语句和命令**:教授如何在...

    PLSQL Developer 13 用户指南 (PLSQL Developer 13.0 User's Guide)

    本指南主要介绍了 PL/SQL Developer 13 的使用方法及相关功能,旨在帮助用户更高效地进行数据库编程。 #### 二、安装指南 ##### 2.1 系统要求 - **操作系统**:支持 Windows、Linux 和 macOS。 - **Oracle 客户端**...

    plsql developer 7.0 最新中文手册

    PL/SQL Developer是一款由...通过这份PL/SQL Developer 7.0的中文手册,用户将能全面了解并掌握如何有效地使用这款工具,提升Oracle数据库开发和管理的工作效率。无论是初学者还是经验丰富的开发者,都能从中受益。

    pl-sql 培训资料

    - 游标用于逐行处理查询结果,是PL/SQL中处理数据集的重要工具。 在学习PL/SQL时,理解这些基本概念至关重要。实际操作时,应结合具体的Oracle环境和实际需求进行练习,加深理解。同时,不断探索和学习高级特性,...

    Oracle11g设计与开发教程课后习题

    11. SQL查询:ORDER BY子句用于排序,未指定排序则按默认顺序,SELECT语法至少包含SELECT和FROM,DISTINCT去除重复行,UNION合并结果集,GROUP BY用于分组统计。 12. 事务控制:DECLARE不是事务控制关键字,Oracle...

    PLSql循序渐进全面学习教程--Oracle

    PL/SQL还支持使用连接符号`||`来合并不同的列或字符串,生成一个有意义的输出。这在展示数据时非常方便,例如,可以将员工的`first_name`和`last_name`连接在一起,再加上逗号和`title`。 处理NULL值是数据库操作中...

    Oracle SQL最佳实践

    在进行数据查询时,为了去除结果集中的重复行,我们通常会使用 `DISTINCT` 关键字。然而,在某些场景下,这种方法可能会导致不必要的排序操作(`SORT OPERATION`),从而降低查询效率。为了避免这种情况,我们可以...

    Oracle PLSQL测试题与答案(绝对经典).docx

    - 当表中存在大量重复数据时,位图索引(Bitmap Index)可能是更合适的选择,因为它在处理大量重复值时效率更高。 8. **表约束**: - `CHECK`约束用于确保列值在特定条件范围内。 9. **事务特性**: - 游标配合...

    ORACLE__SQL语句教学

    存储过程和函数是PL/SQL的特性,用于封装一系列SQL和PL/SQL语句,可重复使用并提高代码效率。存储过程没有返回值,而函数必须返回一个值。 11. **触发器(TRIGGER)** 触发器是一种在特定数据库事件(如INSERT、...

    oracle使用管理笔记(一些经验的总结)

    PL/SQL语法数据类型 57 (6)PL/SQL进阶控制结构 60 (7)PL/SQL进阶分页过程 62 (8)PL/SQL进阶例外 62 (9)视图 62 22.数据库管理+表的逻辑备份与恢复 63 23.数据字典和动态性能视图 67 24.oracle的卸载 69 25.尚学堂SQL...

    oracle script

    8. **存储过程和函数**:预编译的SQL和PL/SQL代码块,可重复使用,提高代码效率。 9. **动态SQL**:允许在运行时构建和执行SQL语句,增加了脚本的灵活性。 10. **数据库链接**:允许从一个数据库访问另一个数据库...

    oracle异库同表名的两个数据库中数据合并或数据表结构的修改

    使用PL/SQL Developer工具进行比较 PL/SQL Developer是一款功能强大的Oracle开发工具,它提供了丰富的特性用于提高开发效率。其中,“Compare User Objects”功能可以帮助我们快速比较两个不同数据库中的用户对象...

    o9i_dwperfcomp_dwflowOracle9i 数据仓库增强

    这一系列增强覆盖了从数据加载、转换、构建到查询的全过程,尤其在合并/更新插入、外部表、聚合、动态内存管理、实体化视图、快速刷新、PL/SQL、索引跳扫和位图联接索引等方面进行了显著改进。下面,我们将详细解析...

Global site tag (gtag.js) - Google Analytics