postgresql-DML

news2024/12/28 19:12:25

DML 语句

  • 创建示例表
  • 插入数据
    • 插入单行数据
    • 插入多行数据
    • 复制数据
    • 返回插入的数据
  • 更新数据
    • 单表更新
    • 跨表更新
    • 返回更新后的数据
  • 删除数据
    • 单表删除
    • 跨表删除
    • 返回被删除的数据
  • 合并数据
    • MERGE 语句
    • INSERT ON CONFLICT
  • DML 语句与 CTE

创建示例表

CREATE TABLE dept (
 department_id int NOT NULL,
 department_name varchar(30) NOT NULL,
 CONSTRAINT dept_pkey PRIMARY KEY (department_id)
);
CREATE TABLE emp (
 employee_id int NOT NULL,
 first_name varchar(20) NULL,
 last_name varchar(25) NOT NULL,
 hire_date date not null default current_date,
 salary numeric(8,2) NULL,
 manager_id int NULL,
 department_id int NULL,
 CONSTRAINT emp_pkey PRIMARY KEY (employee_id),
 CONSTRAINT fk_emp_dept FOREIGN KEY (department_id) REFERENCES
dept(department_id) ON DELETE CASCADE,
 CONSTRAINT fk_emp_manager FOREIGN KEY (manager_id) REFERENCES
emp(employee_id)
);

插入数据

插入单行数据

语法

INSERT INTO table_name(column1, column2, ...)
VALUES (value1, value2, ...);

value1 是 column1 的值,value2 是 column2 的值

insert into public.dept(department_id,department_name)
values(10,'Administration');

插入多行数据

postgresql中的insert语句支持一次插入多行数据,在values之后使用逗号进行分隔

INSERT INTO emp
VALUES (200, 'Jennifer', 'Whalen', '2020-01-01', 4400.00, NULL, 10),
 (201, 'Michael', 'Hartstein', '2020-02-02', 13000.00, NULL, 20),
 (202, 'Pat', 'Fay', default, 6000.00, 201, 20);
select * from emp;

在这里插入图片描述

复制数据

-- 创建表emp1表结构和emp一样
create table emp1 (like emp);

insert into select 语句可以将一个查询语句的结果插入表中

-- 将查询到的emp数据插入到emp1中
insert into emp1 select * from emp;

返回插入的数据

insert into dept 
values (30,'Purchasing')
returning department_id,department_name ;

在这里插入图片描述

更新数据

单表更新

postgresql 使用 update 语句更新表中已有的数据,基本的语法如下:

UPDATE table_name
 SET column1 = value1,
 column2 = value2,
 ...
WHERE conditions;

其中,WHERE 决定了需要更新的数据行,只有满足条件的数据才会更新;如果省略 WHERE
条件,将会更新表中的所有数据,需要谨慎使用

-- 将编号为 200 的员工从原部门调动到 Marketing,并且涨薪 1000
UPDATE emp1
 SET salary = salary + 1000,
 department_id = 20
WHERE employee_id = 200;

跨表更新

-- 跨表更新
-- postgresql 还支持通过关联其他表中的数据进行更新。以下语句利用 emp 中的数据更新 emp1 表
update emp1 e
set salary = t.salary 
from emp t
where t.employee_id  = e.employee_id;

在这里插入图片描述

返回更新后的数据

postgresql 同样对 update 语句进行了扩展,支持使用 returning 返回更新后的数据值

-- 跨表更新
-- postgresql 还支持通过关联其他表中的数据进行更新。以下语句利用 emp 中的数据更新 emp1 表
update emp1 e
set salary = t.salary 
from emp t
where t.employee_id  = e.employee_id
-- * 返回更新后表中的所有列
returning *;

在这里插入图片描述

删除数据

单表删除

-- table 表名 相当于select * from 表名
table emp1;
-- 只有满足 WHERE 条件的数据才会被删除;如果省略,将会删除表中所有的数据
-- 删除 emp1 中员工编号为 201 的数据
-- 如果没有编号为 201 的记录,不会删除任何数据
delete from cps.public.emp1 e where e.employee_id  = 202;

跨表删除

-- postgresql 同样支持通过关联其他表进行数据删除
-- 利用 emp 表删除 emp1 表中全部的数据
delete
from emp1
using emp
where emp1.employee_id = emp.employee_id;

跨表删除使用 using 关键字引用其他的表,而不是 join。以上语句了 emp1 中员工
编号存在于 emp 表中的数据,等价于以下子查询实现:

delete
from emp1
where emp1.employee_id in (select employee_id from emp);

返回被删除的数据

postgresql 中的 delete 语句也可以使用 returning 返回被删除的数据。例如:

-- 删除所有数据并且返回这些记录
delete
from emp1
returning *;

在这里插入图片描述

合并数据

MERGE 语句

在这里插入图片描述
创建示例表

CREATE TABLE account (
 id INTEGER PRIMARY KEY,
 balance NUMERIC NOT NULL,
 status VARCHAR(1) NOT NULL CHECK (status IN ('Y', 'N'))
);
-- 使用以下语句为 account 表新增一条记录:
/*
 * WHEN MATCHED THEN:数据匹配上时候的操作
 * WHEN NOT MATCHED THEN:数据没有匹配上时候的操作
 */
MERGE INTO account a
USING (VALUES(1, 0, 'Y')) s(id, balance, status)
ON a.id = s.id
WHEN MATCHED THEN
 UPDATE SET balance = s.balance, status = s.status
WHEN NOT MATCHED THEN
 INSERT (id, balance, status)
 VALUES (s.id, s.balance, s.status);

由于 id 等于 1 的记录不存在,以上语句将会执行 WHEN NOT MATCHED THEN 分支,插
入一条新的记录。

接下来我们将插入源数据中的 balance 修改为 100,再次执行 MERGE 语句:

-- 以下语句将会执行 WHEN MATCHED THEN 分支,更新 account 表中 id 等于 1 的记录。
MERGE INTO account a
USING (VALUES(1, 100, 'Y')) s(id, balance, status)
ON a.id = s.id
WHEN MATCHED THEN
 UPDATE SET balance = s.balance, status = s.status
WHEN NOT MATCHED THEN
 INSERT (id, balance, status)
 VALUES (s.id, s.balance, s.status);
--最后,我们在 MERGE 语句中增加一个分支,用于删除数据:
/*
 * 语句中的 WHEN MATCHED AND s.status = ‘N’ THEN 表示如果源数据存在,
 * 并且源数据中的状态为 N,则删除目标表中的对应记录
 * */
MERGE INTO account a
USING (VALUES(1, 100, 'N')) s(id, balance, status)
ON a.id = s.id
WHEN MATCHED AND s.status = 'N' THEN
 DELETE
WHEN MATCHED THEN
 UPDATE SET balance = s.balance, status = s.status
WHEN NOT MATCHED THEN
 INSERT (id, balance, status)
 VALUES (s.id, s.balance, s.status);

INSERT ON CONFLICT

对于 PostgreSQL 14 以及更早版本,可以通过 INSERT INTO … ON CONFLICT… 实现数据
合并的功能
在这里插入图片描述
在这里插入图片描述

--emp 表中已经存在编号为 200 的员工,如果我们再次插入该编号将会提示主键冲突:
--增加冲突处理,从而避免语句出错
INSERT INTO emp
values (200, 'Jennifer', 'Whalen', '2020-01-01', 4400.00, NULL, 10)
--基于 employee_id 字段是否重复进行判断,冲突时不做任何处理
on conflict (employee_id)
do nothing 
;
--emp 表中已经存在编号为 200 的员工,如果我们再次插入该编号将会提示主键冲突:
--增加冲突处理,从而避免语句出错
INSERT INTO emp
values (200, 'Jennifer', 'Whalen', '2020-01-01', 4400.00, NULL, 10)
--基于 employee_id 字段是否重复进行判断,冲突时进行数据更新
on conflict on constraint emp_pkey
do update 
set first_name = EXCLUDED.first_name,
last_name = EXCLUDED.last_name,
hire_date = EXCLUDED.hire_date,
salary = EXCLUDED.salary,
manager_id =EXCLUDED.manager_id,
department_id = EXCLUDED.department_id;

/*该员工的部门编号在前面被修改为 20;我们通过主键约束 emp_pkey 进行重复数据的判断,
*然后更新该员工的数据;
*EXCLUDED 是一个特殊的表,代表了原本应该插入的数据行;最终该
*员工的部门编号被更新为 10。
*/
select * from emp e where e.employee_id =200;

在这里插入图片描述

DML 语句与 CTE

除了 SELECT 语句之外,INSERT、UPDATE 或者 DELETE 语句也可以与 CTE 一起使用。
我们可以在 CTE 中使用 DML 语句,也可以将 CTE 用于 DML 语句
如果在 CTE 中使用 DML 语句,我们可以将数据修改操作影响的结果作为一个临时表,然
后在其他语句中使用

-- 创建一个员工历史表
CREATE TABLE employees_history
AS SELECT * FROM employees WHERE 1 = 0;

WITH deletes AS (
-- 返回删除的数据
 DELETE FROM employees
 WHERE employee_id = 206
 RETURNING *
)
-- 将删除的数据插入到employees_history表中
INSERT INTO employees_history
SELECT * FROM DELETEs;

-- 查询数据
SELECT employee_id, first_name, last_name
FROM employees_history;

我们首先创建了一个记录员工历史信息的 employees_history 表;然后使用 DELETE 语句定
义了一个 CTE,RETURNING *返回了被删除的数据,构成了结果集 deletes;然后使用 INSERT
语句记录被删除的员工信息

WITH inserts AS (
 INSERT INTO employees
 VALUES
(207,'William','Gietz','11','515.123.8181','2002-06-07','AC_ACCOUNT',8800.00,NULL,205,110)
 RETURNING *
)
-- inserts插入的结果集插入到employees_history表中
INSERT INTO employees_history
SELECT * FROM inserts;
/*
 * returning 在 CTE 中,UPDATE 语句修改了一个员工的月薪;但是为了记录修改之前的数据,
 * 我们插入 employees_history 的数据仍然来自 employees 表。
 * 因为在一个语句中,所有的操作都在一个事务中,所以主查询中的 employees 是修改之前的状态
*/
WITH updates AS (
 UPDATE employees
 SET salary = salary + 500
 WHERE employee_id = 206
 RETURNING *
)
INSERT INTO employees_history
SELECT * FROM employees WHERE employee_id = 206;
--获取更新之后的数据,直接使用 updates
WITH updates AS (
 UPDATE employees
 set salary = salary - 500
 WHERE employee_id = 206
 RETURNING *
)
SELECT employee_id,first_name, last_name, salary
FROM updates;

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

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

相关文章

面向Ai设计的Mojo编程语言支持下载,当前只有Linux系统版本

据了解,Mojo是Modular AI公司开发的专门面向AI设计的编程语言,号称比Python快68000倍。 Mojo现已开放本地下载运行,除了编译器之外,Mojo SDK还包括一整套开发者和IDE工具,并用来构建和迭代 Mojo应用。 公司方面表示&…

leetcode 589. N 叉树的前序遍历(java)

N 叉树的前序遍历 题目描述前序遍历后序遍历 题目描述 难度 - 简单 LC - 589.N叉树的前序遍历 给定一个 n 叉树的根节点 root ,返回 其节点值的 前序遍历 。 n 叉树 在输入中按层序遍历进行序列化表示,每组子节点由空值 null 分隔(请参见示例…

RK3399平台开发系列讲解(内核调试篇)USB摄像头快速测试

🚀返回专栏总目录 文章目录 一、检测设备二、安装必要的库三、 mjpeg-stream 安装四、实时预览沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 本篇介绍如何快速测试 USB 摄像头。 一、检测设备 将 USB 摄像头插上,查看是否找到设备,输入指令:v4l2-ctl --list-d…

vuex中actions异步调用以及读取值

项目场景: 提示:这里简述项目相关背景: 将根据segmentId查出来的合同信息托管到vuex中,让每个人都可以获取到合同信息 描述以及问题点 1:调用vuex异步函数的语法是 this.$store.dispatch(actions方法名,值) 2&#…

JUC并发编程--------线程安全篇

目录 什么是线程安全性问题? 如何实现线程安全? 1、线程封闭 2、无状态的类 3、让类不可变 4、加锁和CAS 并发环境下的线程安全问题有哪些? 1、死锁 2、活锁 3、线程饥饿 什么是线程安全性问题? 我们可以这么理解&#…

计算机竞赛 基于设深度学习的人脸性别年龄识别系统

文章目录 0 前言1 课题描述2 实现效果3 算法实现原理3.1 数据集3.2 深度学习识别算法3.3 特征提取主干网络3.4 总体实现流程 4 具体实现4.1 预训练数据格式4.2 部分实现代码 5 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 基于深度学习机器视觉的…

如何设计一个复杂的业务系统

一、设计要干啥 作为一个企业级应用架构,自然会把专注点转移到业务应用功能性设计本身上来。现在来说对于一个复杂业务架构进行设计,我们要想做到又快又好,无非是两种情况:一是架构师本身对业务理解很深、能力超强、炉火纯青&…

QT QMdiArea控件 使用详解

本文详细的介绍了QMdiArea控件的各种操作,例如:新建界面、源代码、添加界面、移除一个子窗口、设置活动子窗口、子窗口级联排列、子窗口平铺排列、关闭当前子窗口、关闭当前子窗口、返回当前子窗口、返回当前子窗口、返回子窗口列表、信号槽、单击信号、…

使用python-docx对doc文档修改页眉时,遇到的一点小问题

之前在百度和google搜到的也修改页眉的方式,代码如下 import docx # 打开 Word 文档 doc docx.Document(sample.docx) # 遍历每个节 for section in doc.sections: # 获取节的页眉 header section.header # 获取页眉中的段落 p header.paragraphs[0] # 替换段落…

冒泡排序、选择排序、插入排序、希尔排序

冒泡排序 基本思想 代码实现 # 冒泡排序 def bubble_sort(arr):length len(arr) - 1for i in range(length):flag Truefor j in range(length - i):if arr[j] > arr[j 1]:temp arr[j]arr[j] arr[j 1]arr[j 1] tempflag Falseprint(f第{i 1}趟的排序结果为&#…

基于51单片机+DS1302时钟模块+4位数码管显示

一、DS1302时钟模块简介 二、绘制Proteus 仿真电路图 三、编写51单片机代码 #include "DS1302.h"// 位定义 sbit DS1302_DATA P3^3; sbit SCLK P3^2; sbit RST P3^1;// 向DS1302写一个字节 void DS1302_Write_Byte(unsigned char addrOrData) {unsigned char i;f…

RocketMQ的架构及概念

RocketMQ就是一个消息中间键用于实现异步传输与解耦 那什么是消息中间键呢? 消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,它可以在分布式环境下扩展…

CSP 201312-1 出现次数最多的数

答题 用两个map&#xff0c;一个map记录每个数出现的次数并降序排序&#xff0c;另一个map将次数作为键&#xff0c;数本身作为值&#xff0c;降序排序&#xff0c;搞定 #include<iostream> #include<map> using namespace std; int main(){map<int,int,great…

arm栈推导

按照栈生长方向分&#xff1a;可以分为递增栈&#xff08;向高地址生长&#xff09;&#xff1b;递减栈&#xff08;向低地址生长&#xff09; 按照sp执行位置来分&#xff1a;满栈&#xff08;sp指向栈顶元素的位置&#xff09;&#xff1b;空栈&#xff08;sp指向即将入栈的…

ChatGPT 和 Elasticsearch:APM 工具、性能和成本分析

作者&#xff1a;LUCA WINTERGERST 在本博客中&#xff0c;我们将测试一个使用 OpenAI 的 Python 应用程序并分析其性能以及运行该应用程序的成本。 使用从应用程序收集的数据&#xff0c;我们还将展示如何将 LLMs 成到你的应用程序中。 在之前的博客文章中&#xff0c;我们构建…

SpringBoot+Vue 整合websocket实现简单聊天窗口

效果图 1 输入临时名字充当账号使用 2 进入聊天窗口 3 发送消息 &#xff08;复制一个页面&#xff0c;输入其他名字&#xff0c;方便展示效果&#xff09; 4 其他窗口效果 代码实现 后端SpringBoot项目&#xff0c;自行创建 pom依赖 <dependency><groupId…

docker安装xxl-job连接数据库时显示无法连接问题

背景&#xff1a; 在项目中需要定时任务调度&#xff0c;需要在docker容器中安装xxl-job 遇到的问题 部署成功后&#xff0c;可以访问xxl-job登录界面&#xff0c;点登录没反应&#xff0c;但过一段时间就弹出数据库拒绝连接&#xff0c;说MyBatis连接用户失败 原因&#xf…

华为云API图像识别Image的趣味性—AI识别迈克尔·杰克逊

云服务、API、SDK&#xff0c;调试&#xff0c;查看&#xff0c;我都行 阅读短文您可以学习到&#xff1a;人工智能AI图像识别的图像识别、名人识别 1 IntelliJ IDEA 之API插件介绍 API插件支持 VS Code IDE、IntelliJ IDEA等平台、以及华为云自研 CodeArts IDE&#xff0c;基…

深度学习算法

深度学习算法 1. 各种网络框架及其联系1.1 两阶段与一阶段区别1.1.1 detectron算法框架套路&#xff1a;1.1.2 multi-stage1.1.3 two-stage 算法1.1.4 one-stage 算法 2. 常用算法2.1 SS(选择性搜索算法&#xff0c;Selective Search) 3. 神经元模型4. 神经网络分类4.1 前馈神经…

Linux内核分析与应用5-中断

本系列是对 陈莉君 老师 Linux 内核分析与应用[1] 的学习与记录。讲的非常之好&#xff0c;推荐观看 留此记录&#xff0c;蜻蜓点水,可作抛砖引玉 中断机制概述 中断是CPU对系统发生的某个事件作出的一种反应, 当中断发生时,CPU暂停正在执行的程序,保留现场后,自动转去执行相应…