`

MERGE函数的妙用案例

 
阅读更多

 

本文来至《剑破冰山》-Oracle开发艺术
/******************************************************************************
 *探索merge方法
 *
 *****************************************************************************/
 --1.what is merge?
 /*
 for exmple
 从T1表更新数据到T2表,如果T2表NAME字段的记录在T1表中存在,就将MONEY字段的值累加,如果不
 存在,将T1表的记录插入到T2表中。
 */
 DROP TABLE T1;
 CREATE TABLE t1(NAME VARCHAR2(20),money NUMBER);
 INSERT INTO t1 VALUES('A',100);
 INSERT INTO t1 VALUES('B',200);
 
 DROP TABLE t2;
 CREATE TABLE t2(NAME VARCHAR2(20),money NUMBER);
 INSERT INTO t2 VALUES('A',300);
 INSERT INTO t2 VALUES('C',100);
 COMMIT;
 
 SELECT * FROM t1;
 /*
  大家都知道,按照一般逻辑思路,该需求至少需要update和insert两条sql才能完成,
  如考虑在PL/SQL中用纯编程语言思路实现,则必须要考虑逻辑判断,这样就显得更麻烦了。
  merge语句的出现正是为了解决此类问题,使用merge语句,可以实现“存在则update,
  不存在则insert”的逻辑
 */
 --以下是使用merge语句简洁明了地单条实现该需求,如下:
MERGE INTO t2 USING t1 ON (t1.NAME=t2.NAME)
WHEN MATCHED THEN
  UPDATE SET t2.money = t1.money+t2.money WHEN NOT MATCHED THEN
  INSERT VALUES
    (t1.NAME,t1.money
    );
COMMIT;

SELECT * FROM t2;

/******************
merge的巧妙用法 
*******************/
/**
 案例1
 需求为:将如下TEST记录ID=1 的 NAME 改为 ID=2 的 NAME 值,
 将 ID=2 的 NAME 改为 ID=1 的 NAME 值
*/
DROP TABLE test;
CREATE TABLE test(ID NUMBER,NAME VARCHAR2(20));
INSERT INTO test VALUES(1,'a');
INSERT INTO test VALUES(2,'b');
COMMIT;
SELECT * FROM test;

--如果执行如下:
UPDATE test SET NAME =(SELECT NAME FROM test WHERE ID=2)WHERE ID =1;
--此时ID=1的NAME值已经变了,就不可能用如下代码来更新了。
UPDATE test SET NAME =(SELECT NAME FROM test WHERE ID=1)WHERE ID=2;

--如果是过程就很简单了,可以把原来的值先存储起来。但是是否但条件SQL一定不行呢?
--其实单条SQL是可以解决的,可以考虑灵活利用merge特性。可考虑先构造一个虚拟表T,
--然后再根据此虚拟表T和真实的TEST表进行merge更新,这样就方便快捷地完成了。
--1.构造虚拟表
SELECT 1 ID, (SELECT NAME FROM TEST WHERE ID = 2) NAME
  FROM DUAL
UNION ALL
SELECT 2, (SELECT NAME FROM TEST WHERE ID = 1) FROM DUAL;

--有了此思路,结合前面所学的merge知识,可以通过如下简洁的代码来完成更新。
MERGE INTO TEST
USING (SELECT 1 ID, (SELECT NAME FROM TEST WHERE ID = 2) NAME
         FROM DUAL
       UNION ALL
       SELECT 2, (SELECT NAME FROM TEST WHERE ID = 1) FROM DUAL
       
       ) T
ON (TEST.ID = T.ID)
WHEN MATCHED THEN
  UPDATE SET TEST.NAME = T.NAME
WHEN NOT MATCHED THEN
  INSERT VALUES (T.ID, T.NAME);

SELECT * FROM test;

--本案例用的是merge的方法,当然,其中构造虚拟表也是一个非常重要的思路,如果只是
--查询出改变后的结果而不是真实地进行更新,则可以不采用merge,直接采用如下方式
--取出结果
WITH t AS (
SELECT 1 ID, (SELECT NAME FROM TEST WHERE ID = 2) NAME
  FROM DUAL
UNION ALL
SELECT 2, (SELECT NAME FROM TEST WHERE ID = 1) FROM DUAL
)
SELECT TESt.ID, T.NAME FROM TEST, T WHERE TEST.ID = T.ID;

--案例2
--通过merge 可以得到一个非常有用的方法,就是只要检查出更新后的结果集,就可以
--利用该结果集来更新原表记录,即MERGE+ROWID方法

--案例2是案例1的延伸,改变了案例1的处理思路,不再采用构造虚拟表T来关联TEST表的方式,
--而是直接把真实结果用SELECT的方式取出,然后利用这个结果集更新原表记录。
MERGE INTO TEST
USING (WITH T AS (SELECT 1 ID, (SELECT NAME FROM TEST WHERE ID = 2) NAME
                    FROM DUAL
                  UNION ALL
                  SELECT 2, (SELECT NAME FROM TEST WHERE ID = 1) FROM DUAL)
  SELECT TEST.ID, TEST.ROWID AS RN, T.NAME
    FROM TEST, T
   WHERE T.ID = TEST.ID) N ON (TEST.ROWID = N.RN) WHEN MATCHED THEN
    UPDATE SET TEST.NAME = N.NAME
  WHEN NOT MATCHED THEN
    INSERT VALUES (N.ID, N.NAME);
SELECT * FROM test;

--后记
/******
 直接UPDATE一个子查询的写法也是可以的,但是却又很多限制,稍微复杂的查询就容易出错。
 此时用MERGE是最好的办法,结合ROWID的方法,可快速准确地利用一个已查询出的结果集来
 更新自己,是一个非常好的思路,希望对大家有借鉴。
****/ 
 
 

 

分享到:
评论

相关推荐

    WinMerge VC6.0

    通过对这个工作空间文件的分析,开发者可以深入了解WinMerge的模块划分、类结构以及函数实现,这对于学习MFC编程和理解WinMerge的内部机制非常有帮助。 五、老版本的价值 尽管WinMerge已经有更新的版本,但老版本的...

    Merge Sort

    在这个案例中,我们关注的是使用C++语言在Visual Studio 2008环境下实现Merge Sort算法。 **1. 分治法介绍** 分治法是计算机科学中一种重要的解决问题的方法,它将一个复杂的问题分解成两个或更多的相同或相似的子...

    Python中泛型函数应用案例.zip

    下面将深入探讨Python中泛型函数的应用案例。 首先,Python的类型注解是自Python 3.5版本引入的特性,它允许我们在函数定义时添加类型提示,以帮助编译器、IDE和开发者理解函数期望的输入和输出类型。例如,一个...

    python数据函数使用案例.rar

    本资源"python数据函数使用案例.rar"显然包含了与Python中处理数据相关的实践示例,可能涵盖了读取、清洗、转换、分析数据等多个方面。这里我们将深入探讨Python中的几个关键数据处理库以及它们的相关函数。 首先,...

    mapreduce案例代码及案例涉及文件

    在这个案例中,注释可能会解释如何定义Map函数,它如何将输入数据转换为适合Reduce阶段的格式。Map任务通常是并行执行的,可以充分利用集群中的多台机器资源。 **Reduce阶段**: Reduce阶段紧随Map之后,它的主要...

    系统函数.md

    本篇文章将围绕系统函数这一主题展开详细介绍,主要涵盖时间日期函数、数学函数以及数组常用函数等内容。通过学习这些基础而重要的函数,我们可以更好地理解和掌握在编程过程中如何有效地处理时间和数学运算,同时也...

    数据结构课程设计案例精编STL.rar

    案例可能涉及到splice、reverse、merge等操作。 3. **Set和Map应用**:set是有序的不重复元素集合,而map是键值对的关联容器。它们都基于红黑树实现,可以快速查找。案例可能涵盖插入、删除、查找以及使用lower_...

    分治法合并排序算法实现merge

    在本案例中,我们将讨论如何利用分治法实现合并排序(Merge Sort),这是一种效率较高的排序算法,其时间复杂度为O(n log n)。 合并排序的基本思想是将原始数组分为两个相等(或接近相等)的部分,对每一部分分别...

    Excel-VBA宏编程实例源代码-使用Merge排序阵列.zip

    这个“Excel-VBA宏编程实例源代码-使用Merge排序阵列.zip”文件是一个专门针对VBA宏编程的实践案例,尤其是关于数组的Merge排序方法。下面将详细解释相关知识点。 一、VBA宏语言编程 VBA是内置在Microsoft Office...

    php常用数组函数实例小结

    1. array_merge函数 array_merge函数用于合并一个或多个数组。当使用array_merge时,第一个数组中的元素会被放置在结果数组的开头。之后的数组中的元素依次追加到结果数组中。如果数组中存在相同键名的字符串键值,...

    05-3D位姿变换案例1

    在上面的代码中,我们定义了merge_pose函数,该函数将旋转矩阵和平移向量合并成一个4x4矩阵。我们也定义了split_pose函数,该函数将4x4矩阵分解成旋转矩阵和平移向量。 4. 位姿变换实践: 在本案例中,我们需要...

    img_merge_hdf.zip_hdf_matlab hdf_高通滤波

    在这个案例中,"img_merge_hdf.m"可能包含了对HDF(Hierarchical Data Format)文件的读取、处理和可能的保存。HDF是一种灵活的数据存储格式,常用于科学数据,包括图像数据。MATLAB支持HDF4和HDF5格式,允许用户...

    merge_excel.zip

    本案例中,"merge_excel.zip"文件提供的就是一个使用Python编程来批量合并Excel表格的示例。这个压缩包可能包含一个或多个Python脚本,以及可能的说明文档,用于演示如何实现这一功能。下面将详细讲解如何使用Python...

    数据分析案例所需文件数据

    同样地,我们可以用Pandas读取并处理这个文件,然后使用`merge()`函数将此信息与其他数据集合并,以增强分析的深度和准确性。 最后,"state-areas.csv" 文件可能包含了美国各州的面积数据,这为我们提供了地理信息...

    Python数据分析案例.zip

    Pandas的merge()和concat()函数用于数据融合,groupby()用于按特定列分组,sort_values()进行排序。 7. 描述性统计:计算均值、中位数、标准差等统计量,了解数据分布特性。Pandas提供了describe()函数,一键获取...

    Python机器学习-原理算法及案例实战微课视频版课件第章Python常用机器学习库其他库.pptx

    Python机器学习-原理算法及案例实战微课视频版课件第章Python常用机器学习库其他库.pptx 本资源摘要信息是关于Python机器学习的常用库和算法的介绍,特别是OpenCV库的使用和应用。OpenCV是一个基于C++实现的Python...

    oracle数据匹配merge into的实例详解

    在这个案例中,源表是`L_TABLE`,目标表是`Z_TABLE`,它们具有相同的结构,但没有主键。 场景如下: 1. 如果两表的所有字段值都相等,则不进行任何处理。 2. 如果有部分字段不一致,则更新目标表的相应记录。 3. ...

    【SparkSql篇02】SparkSql之自定义UDF和UDAF函数1

    在这个案例中,我们定义了一个名为 `toUpper` 的函数,将字符串转为大写。 ```scala // 定义 toUpper 函数 def toUpper(name: String): String = name.toUpperCase() // 注册 UDF spark.udf.register("toUpper", ...

Global site tag (gtag.js) - Google Analytics