PostgreSQL

PostgreSQL 知识量:10 - 51 - 182

5.6 高级操作><

归并数据- 5.6.1 -

在 PostgreSQL 中,归并数据通常指的是将两个或多个数据集合并为一个数据集的操作。这个操作可以包括插入新记录、更新现有记录或根据某些条件进行冲突处理。在 PostgreSQL 中,可以使用 INSERT ... ON CONFLICT 语法来实现归并操作,也被称为 UPSERT(更新 + 插入)。

下面是 INSERT ... ON CONFLICT 语法的基本结构:

INSERT INTO table_name (column1, column2, ...)    
VALUES (value1, value2, ...)    
ON CONFLICT (constraint_column)    
DO UPDATE SET column1 = value1, column2 = value2, ...;

其中,table_name 是要插入或更新数据的表名,column1, column2, ... 是表中的列名,value1, value2, ... 是要插入或更新的值。constraint_column 是用于冲突处理的约束列,通常是一个唯一约束列。

在 ON CONFLICT 子句中,指定了冲突处理的约束列,如果该列存在冲突,则会执行 DO UPDATE 部分中的更新操作。如果不存在冲突,则执行正常的插入操作。

以下是一个示例:

INSERT INTO employees (id, name, age)    
VALUES (1, 'John Doe', 30)    
ON CONFLICT (id)    
DO UPDATE SET name = EXCLUDED.name, age = EXCLUDED.age;

在上面的示例中,如果 id 列存在冲突,则会将冲突的记录更新为 name = 'John Doe' 和 age = 30。如果不存在冲突,则会插入一条新记录。

需要注意的是,使用 INSERT ... ON CONFLICT 语法时,需要确保目标表具有适当的唯一约束或主键约束,以便正确处理冲突。同时,更新操作会根据约束条件选择性地更新现有记录,而不是对整个表进行全量更新。

批量插入- 5.6.2 -

可以使用多种方法进行批量插入。以下是一些常见的方法:

1. 使用INSERT INTO…VALUES(),(),()语句:

虽然这不是最高效的方法,但对于较小的数据集,可以简单地使用多个值列表。

INSERT INTO table_name (column1, column2, ...)  
VALUES   
(value1a, value2a, ...),  
(value1b, value2b, ...),  
...  
(value1z, value2z, ...);

2. 使用INSERT INTO…SELECT…语句:

用于从一个表中选择数据并将其插入到另一个表中。这种操作通常用于复制数据、从一个表复制数据到另一个表,或者在满足某些条件时从一个表复制数据到另一个表。

INSERT INTO target_table (column1, column2, ...)  
SELECT column1, column2, ...  
FROM source_table  
WHERE condition;

3. 使用 COPY 命令:

COPY 命令通常用于从文件批量导入数据到 PostgreSQL 数据库。首先,需要将数据导出到一个文件(例如 CSV),然后使用 COPY 命令导入到数据库。

COPY table_name (column1, column2, ...) FROM '/path/to/your/csvfile.csv' WITH CSV HEADER;


批量更新- 5.6.3 -

在 PostgreSQL 中,可以使用多种方法进行批量更新。以下是一些常见的方法:

1. 使用单个 UPDATE 语句:

这是最简单的方法,只需要使用标准的 UPDATE 语句。

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

2. 使用 CASE 表达式:

在 UPDATE 语句中,可以使用 CASE 表达式来根据条件更新不同的值。

UPDATE table_name    
SET column1 = CASE id    
WHEN id1 THEN value1    
WHEN id2 THEN value2    
...    
ELSE column1    
END,    
column2 = CASE id    
WHEN id1 THEN valueA    
WHEN id2 THEN valueB    
...    
ELSE column2    
END,    
...    
WHERE condition;

3. 使用临时表或子查询:

可以使用临时表或子查询来生成要更新的数据,然后在 UPDATE 语句中引用这些数据。

CREATE TEMP TABLE temp_table AS (SELECT id, value1, value2 FROM table_name WHERE condition);    
UPDATE table_name    
SET column1 = temp.value1, column2 = temp.value2, ...    
FROM temp_table temp    
WHERE table_name.id = temp.id;

4. 使用批量插入和更新:

如果要批量插入和更新数据,可以使用事务来确保数据的一致性。首先,使用 INSERT 语句将数据插入到一个临时表中,然后使用 UPDATE 语句更新目标表。最后,将临时表中的数据删除。

BEGIN;    
INSERT INTO temp_table (id, column1, column2) 
VALUES (value1a, value1b, value1c), (value2a, value2b, value2c), ...;    
UPDATE table_name SET column1 = temp.new_value FROM temp_table temp 
WHERE table_name.id = temp.id;    
DELETE FROM temp_table;    
COMMIT;

关联更新- 5.6.4 -

在 PostgreSQL 中,关联更新是一种常用的操作,它允许根据一个表中的数据更新另一个表的数据。这通常通过 JOIN 语句来实现,使用一个关联条件将两个表连接起来,并根据该条件更新目标表的数据。

以下是关联更新的一般语法:

UPDATE target_table    
SET column1 = value1, column2 = value2, ...    
FROM source_table    
WHERE target_table.column = source_table.column    
AND condition;

 其中:

  • target_table 是想要更新的表。

  • source_table 是用于提供新数据的表。

  • condition 是可选的,用于筛选要更新的行。

通过指定关联条件,可以将两个表连接起来,并使用源表中的数据来更新目标表中的相应行。

以下是一个示例,演示如何使用关联更新将一个表中的数据更新为另一个表中的相应数据:

假设有两个表 orders 和 customers,它们通过 customer_id 列关联。如果想要将 orders 表中的 customer_name 列更新为 customers 表中的相应 name 值,可以使用以下语句:

UPDATE orders    
SET customer_name = customers.name    
FROM customers    
WHERE orders.customer_id = customers.id;

这将根据关联条件 orders.customer_id = customers.id 将 orders 表中的 customer_name 列更新为 customers 表中的相应 name 值。

批量删除- 5.6.5 -

可以使用多种方法进行批量删除操作。以下是一些常见的方法:

1. 使用 DELETE 语句:

DELETE FROM table_name WHERE condition;

在 DELETE 语句中,需要指定要删除的表名和删除条件。这将删除满足条件的所有行。

2. 使用 DELETE 和 RETURNING:

如果希望获取被删除行的数据,可以使用 DELETE 和 RETURNING 子句。

DELETE FROM table_name WHERE condition RETURNING *;

这将返回被删除的行的数据。

3. 使用 DELETE 和 USING:

如果需要指定多个条件来删除行,可以使用 DELETE 和 USING 子句。

DELETE FROM table_name USING table2 WHERE table_name.column = table2.column AND condition;

这将删除满足条件的所有行,其中 table2 是另一个表,condition 是指定的条件。

4. 使用 TRUNCATE TABLE:

TRUNCATE TABLE 是一个更高效的方法,用于删除表中的所有行,而不记录单个行的删除操作。

TRUNCATE TABLE table_name;

这将删除表中的所有行,而不记录任何单个行的删除操作。注意:TRUNCATE TABLE 是一个不可回滚的操作,并且不会触发任何 DELETE 触发器。

关联删除- 5.6.6 -

关联删除用于根据一个表中的数据删除另一个表中的数据。这通常通过 JOIN 语句来实现,使用关联条件将两个表连接起来,并根据该条件删除目标表中的行。

以下是关联删除的一般语法:

DELETE FROM target_table    
USING source_table    
WHERE condition;

其中:

  • target_table 是想要删除行的表。

  • source_table 是用于提供删除条件的表。

  • condition 是关联条件,用于将两个表连接起来。

通过指定关联条件,可以将两个表连接起来,并使用源表中的数据来删除目标表中的相应行。

以下是一个示例,演示如何使用关联删除从 orders 表中删除与 customers 表中相关联的行:

假设有两个表 orders 和 customers,它们通过 customer_id 列关联。如果想要删除与特定客户相关的所有订单,可以使用以下语句:

DELETE FROM orders    
USING customers    
WHERE orders.customer_id = customers.id AND customers.name = 'John';

这将从 orders 表中删除与 customers 表中 name 列为 'John' 的客户相关联的所有订单。