PostgreSQL 实现 Oracle 多表插入语句

Oracle 数据库提供了一个多表插入功能,也就是 INSERT ALL 语句。这个功能可以方便数据仓库中的 ETL 操作,基于不同逻辑将数据插入一个或者多个不同的表中。

PostgreSQL 被称为开源领域的 Oracle,虽然没有提供 INSERT ALL 语句,但是可以通过递归查询(WITH 语句)实现类似的功能。

首先创建一个源数据表和三个目标表:

CREATE TABLE src_table(id INTEGER NOT NULL PRIMARY KEY,name VARCHAR(10) NOT NULL
);
INSERT INTO src_table VALUES (1, '张三');
INSERT INTO src_table VALUES (2, '李四');
INSERT INTO src_table VALUES (3, '王五');CREATE TABLE tgt_t1 AS
SELECT * FROM src_table WHERE FALSE;CREATE TABLE tgt_t2 AS
SELECT * FROM src_table WHERE FALSE;CREATE TABLE tgt_t3 AS
SELECT * FROM src_table WHERE FALSE;

无条件的多表插入语句

Oracle 中的 INSERT ALL 语句可以将数据输入插入一个或者多个表中,因此也被称为多表插入语句。第一种形式的 INSERT ALL 语句是无条件的插入语句,源数据中的每一行数据都会被插入到每个目标表中。

-- Oracle 语法
INSERT ALLINTO tgt_t1(id, name) VALUES(id, name)INTO tgt_t2(id, name) VALUES(id, name)INTO tgt_t3(id, name) VALUES(id, name)
SELECT * FROM src_table;

执行以上多表插入语句之后,三个目标表中都生成了 3 条记录。

PostgreSQL 可以使用以下 WITH 语句实现无条件的多表插入语句:

WITH s AS (SELECT id, nameFROM src_table
)
,t1 AS (INSERT INTO tgt_t1(id, name)SELECT *FROM s
),
t2 AS (INSERT INTO tgt_t2(id, name)SELECT *FROM s
),
t3 AS (INSERT INTO tgt_t3(id, name)SELECT *FROM s
)
SELECT 1;SELECT * FROM tgt_t1;
ID|NAME  |
--|------|1|张三  |2|李四  |3|王五  |SELECT * FROM tgt_t2;
ID|NAME  |
--|------|1|张三  |2|李四  |3|王五  |SELECT * FROM tgt_t3;
ID|NAME  |
--|------|1|张三  |2|李四  |3|王五  |

其中,s 代表了数据源,t1 实现了 tgt_t1 的数据插入,依此类推。最终通过一个 WITH 语句实现了三个表的插入操作。

💡虽然很多数据库都提供了通用表表达式(WITH 语句),但是目前只有 PostgreSQL 可以将 DML 语句的结果定义为一个通用表表达式。

有条件的多表插入语句

Oracle 提供的另一种形式的 INSERT ALL 语句是有条件的插入语句,可以将满足不同条件的数据插入不同的表中。例如:

-- Oracle 语法
INSERT ALLWHEN id <= 1 THENINTO tgt_t1(id, name) VALUES(id, name)WHEN id BETWEEN 1 AND 2 THENINTO tgt_t2(id, name) VALUES(id, name)ELSEINTO tgt_t3(id, name) VALUES(id, name)
SELECT * FROM src_table;

以上语句在 tgt_t1 中插入了 1 条数据,因为 id 小于等于 1 的记录只有 1 个。tgt_t2 中插入了 2 条数据,包括 id 等于 1 的记录。也就是说,前面的 WHEN 子句不会影响后续的条件判断,每个条件都会单独进行判断。tgt_t3 中插入了 1 条数据,ELSE 分支只会插入不满足前面所有条件的数据。

PostgreSQL 实现以上插入逻辑的方法如下:

WITH s AS (SELECT id, nameFROM src_table
)
,t1 AS (INSERT INTO tgt_t1(id, name)SELECT *FROM sWHERE id <= 1RETURNING id
),
t2 AS (INSERT INTO tgt_t2(id, name)SELECT *FROM sWHERE id BETWEEN 1 AND 2RETURNING id
),
t3 AS (INSERT INTO tgt_t3(id, name)SELECT *FROM sWHERE id NOT IN (SELECT id FROM t1UNION ALL SELECT id FROM t2)
)
SELECT 1;

t1 定义中的查询条件限制了 id 小于等于 1 的记录,同时使用 RETURNING 子句返回了插入 t1 中的所有 id;t2 也采用了类似的处理方式;t3 通过子查询插入了不满足 t1 和 t2 插入条件的其他数据。

💡RETURNING 子句可以返回 DML 语句操作修改的数据,它也是 PostgreSQL 专有的功能。

有条件的 INSERT FIRST 语句

Oracle 还提供了有条件的 INSERT FIRST 语句,它的原理和 CASE 表达式类似,只会执行第一个满足条件的插入语句,然后继续处理源数据中的其他记录。例如:

INSERT FIRSTWHEN id <= 1 THENINTO tgt_t1(id, name) VALUES(id, name)WHEN id BETWEEN 1 AND 2 THENINTO tgt_t2(id, name) VALUES(id, name)ELSEINTO tgt_t3(id, name) VALUES(id, name)
SELECT * FROM src_table;

以上语句和上一个示例的差别在于源数据中的每个记录只会插入一次,tgt_t2 中不会插入 id 等于 1 的数据。

PostgreSQL 模拟以上 INSERT FIRST 语句的方法如下:

WITH s AS (SELECT id, nameFROM src_table
)
,t1 AS (INSERT INTO tgt_t1(id, name)SELECT *FROM sWHERE id <= 1RETURNING id
),
t2 AS (INSERT INTO tgt_t2(id, name)SELECT *FROM sWHERE id BETWEEN 1 AND 2AND id NOT IN (SELECT id FROM t1)RETURNING id
),
t3 AS (INSERT INTO tgt_t3(id, name)SELECT *FROM sWHERE id NOT IN (SELECT id FROM t1UNION ALL SELECT id FROM t2)
)
SELECT 1;

t2 的定义中排除的 t1 中的记录,t3 的定义中排除的 t1 以及 t2 中的记录,以此类推。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/205093.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用c#实现记事本的功能

知识点&#xff1a; openFileDialog1 是一个 Windows 窗体应用程序中的控件&#xff0c;用于实现文件选择对话框的功能。它是 System.Windows.Forms.OpenFileDialog 类的一个实例。 OpenFileDialog 控件允许用户浏览文件系统并选择要打开的文件。它提供了一些属性和方法&#x…

怎样挖掘客户的需求?有哪些方法?

需求是什么&#xff1f; 需求是人们在某一特定的时期内在愿意付出各种可能的成本&#xff08;时间、精力、现金&#xff09;购买某个具体或者虚拟的商品、服务的数量或数量集合。例如肚子饿了又懒得做&#xff0c;在线点餐外送就是一种需求&#xff0c;用户愿意多花费比线下饭…

JAVA8时间日期类详解

JAVA8 时间日期类 LocalDateTime类(用于代替Date类使用) 用于表示没有时区信息的日期和时间,这个类是不可变的,线程安全的,用于处理日期和时间 LocalDateTime类常用API 常用方法 方法名说明public static LocalDateTime now()获取当前日期与时间public static LocalDateTi…

MySQl int(1)、int(20) 的区别到底在哪里

MySQl int(1)、int(20) 的区别到底在哪里 常思一二&#xff0c;便得自然… int(1)数据类型介绍 在MySQL中&#xff0c;INT(1) 是一种定义整数类型的数据字段&#xff0c;其中的数字表示显示宽度而不是存储范围。具体说&#xff0c;INT(1) 中的数字 1 表示显示宽度&#xff0…

前端小技巧: 写一个异步程序示例, 使用任务队列替代promise和async/await等语法糖

异步程序设定场景 1 &#xff09;场景设定 可以使用懒人每做几件事&#xff0c;就要休息一会儿&#xff0c;并且不会影响做事的顺序这种场景来模拟定义单例名称为: lazyMan支持 sleep 和 eat 两个方法支持链式调用 2 ) 调用示例 const lm new LazyMan(www) lm.eat(苹果).…

LinuxBasicsForHackers笔记 --添加和删​​除软件

使用apt处理软件 apt (Advanced Packaging Tool)。可以使用 apt-get 下载和安装新的软件包&#xff0c;也可以用它更新和升级软件。 许多 Linux 用户更喜欢使用 apt 命令而不是 apt-get。它们在很多方面都很相似&#xff0c;但 apt-get 具有更多功能。 搜索包 在下载软件包之…

高级搜索——ST表,离线RMQ问题

文章目录 前言可重复贡献问题ST表的定义ST表的存储结构ST表的预处理预处理的实现 ST表的区间查询对于k的获取区间查询的实现 OJ链接 前言 对于查询区间最值的方法&#xff0c;我们常用的就是线段树&#xff0c;树状数组&#xff0c;单调队列&#xff0c;而树状数组更适合用于快…

解决Qt发送信号指定重载

现象 信号发送者找不到正确的信号函数 connect(ui->LSpinBox,&QSpinBox::valueChanged,ui->hSlider,&QSlider::setValue);QSpinBox的valueChanged函数分为int和QString两种&#xff0c;存在函数重载&#xff0c;需让编译器加以区分。 不区分的话会爆出&#xff1…

让 ChatGPT 永远重复输出一个词,它就能告诉你很多秘密数据?国内的大模型表现如何?

文章目录 让 ChatGPT 永远重复输出一个词&#xff0c;它就能告诉你很多秘密数据&#xff1f;国内的大模型表现如何&#xff1f;文心一言通义千问百川智能智普清言moonshot星火附件ChatGPT Data Extraction Example 让 ChatGPT 永远重复输出一个词&#xff0c;它就能告诉你很多秘…

【互斥锁不当使用导致的条件竞争】2021_DiceCTF_hashbrown

前言 这个题目还挺有意思的&#xff0c;他并不像之前做的题目直接给你一个贴脸的 UAF 等&#xff0c;而是把 UAF 放在了条件竞争的环境下&#xff0c;其实条件竞争这个漏洞在内核中经常出现。 这里题目没有去符号&#xff0c;所以逆向的难度不是很大&#xff0c;但作者似乎在…

Android蓝牙协议栈fluoride(二) - 软件框架

概述 fluoride 协议栈在整个软件框架中作为一个中间件的角色&#xff0c;向上对接APP&#xff0c;向下对接蓝牙芯片。fluoride采用C语言实现&#xff0c;与APP(Jave)通信采用JNI机制&#xff1b;与蓝牙芯片通信使用HCI硬件接口&#xff08;HCI软件协议参考蓝牙核心规范&#x…

[ffmpeg] find 编码器

背景 整理 ffmpeg 中&#xff0c;如何通过名字或者 id 找到对应编码器的。 具体流程 搜索函数 avcodec_find_encoder // 通过 ID 搜索编码器 avcodec_find_encoder_by_name // 通过名字搜索编码器源码分析 ffmpeg 中所有支持的编码器都会注册到 codec_list.c 文件中&…

毕设:《基于hive的音乐数据分析系统的设计与实现》

文章目录 环境启动一、爬取数据1.1、歌单信息1.2、每首歌前20条评论1.3、排行榜 二、搭建环境1.1、搭建JAVA1.2、配置hadoop1.3、配置Hadoop环境&#xff1a;YARN1.4、MYSQL1.5、HIVE(数据仓库)1.6、Sqoop&#xff08;关系数据库数据迁移&#xff09; 三、hadoop配置内存四、导…

笙默考试管理系统-MyExamTest----codemirror(45)

笙默考试管理系统-MyExamTest----codemirror&#xff08;44&#xff09; 目录 笙默考试管理系统-MyExamTest----codemirror&#xff08;44&#xff09; 一、 笙默考试管理系统-MyExamTest----codemirror 二、 笙默考试管理系统-MyExamTest----codemirror 三、 笙默考试…

【华为OD题库-085】路灯照明II-Java

题目 在一条笔直的公路上安装了N个路灯&#xff0c;从位置0开始安装&#xff0c;路灯之间间距固定为100米。 每个路灯都有自己的照明半径&#xff0c;请计算第一个路灯和最后一个路灯之间&#xff0c;无法照明的区间的长度和。输入描述 第一行为一个数N&#xff0c;表示路灯个数…

FFA 2023 明日开幕,Flink 智能诊断、小红书流批一体实践精彩来袭

近年来&#xff0c;流批一体的技术思想势头火热&#xff0c;即“将批处理和流处理相结合&#xff0c;实现更好的数据处理能力”&#xff0c;已成功从理论层面走进现实世界。Flink 是一款高吞吐量、低延迟的流处理引擎&#xff0c;具备统一接口、高性能、低延迟、容错性和可扩展…

绑定域名简单教程

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 &#x1f324;️安装Nginx环境 &…

前端使用socket.io

前端使用socket.io 前言 socket.IO 是一个库&#xff0c;可以在客户端和服务器之间实现 低延迟, 双向 和 基于事件的 通信。使用socket.IO要确保客户端和服务端都是socket.IO构建的。socket.IO内部封装了很多现成的api&#xff0c;比如心跳监测&#xff0c;断开重来等&#x…

2024黑龙江省职业院校技能大赛信息安全管理与评估赛项规程

2024黑龙江省职业院校技能大赛暨国赛选拔赛 “GZ032信息安全管理与评估”赛项规程 极安云科专注技能竞赛&#xff0c;包含网络建设与运维和信息安全管理与评估两大赛项&#xff0c;及各大CTF&#xff0c;基于两大赛项提供全面的系统性培训&#xff0c;拥有完整的培训体系。团队…

【Qt开发流程】之元对象系统

描述 Qt的元对象系统&#xff08;Meta-Object System&#xff09;是Qt框架的核心机制之一&#xff0c;它提供了运行时类型信息&#xff08;RTTI&#xff09;和信号与槽&#xff08;Signals and Slots&#xff09;机制的支持。元对象系统在Qt中扮演了很重要的角色&#xff0c;它…