在PG数据库中,not in 和except的区别

简介: 在PG数据库中,not in 和except的区别


在 PostgreSQL 中,NOT IN 和 EXCEPT 都可以用于从一个结果集中排除某些行,但它们在实现方式、适用场景和性能表现上存在一些区别。以下是详细的对比:

  1. 语法和功能

SELECT column_name
FROM table_name
WHERE column_name NOT IN (SELECT column_name FROM another_table);

SELECT column_name
FROM table_name
EXCEPT
SELECT column_name
FROM another_table;

  1. 处理 NULL 的方式
  1. 性能表现
  1. 适用场景

示例
假设我们有两个表 employees 和 blacklist,需要找出不在黑名单中的员工。

使用 NOT IN:
sql复制

SELECT employee_id
FROM employees
WHERE employee_id NOT IN (SELECT employee_id FROM blacklist);
使用 EXCEPT:
sql复制

SELECT employee_id
FROM employees
EXCEPT
SELECT employee_id
FROM blacklist;
如果 blacklist 表中包含 NULL,NOT IN 查询将返回空结果,而 EXCEPT 查询仍然可以正确返回结果。

总结

场景 1:多条件筛选
假设我们有两个表 employees 和 contractors,分别存储员工和合同工的信息。我们需要找出在 employees 表中但不在 contractors 表中的员工信息,同时只选择特定部门(如 IT 部门)的员工。

sql复制

SELECT name, department
FROM employees
WHERE department = 'IT'
EXCEPT
SELECT name, department
FROM contractors
WHERE department = 'IT';
此查询返回在 IT 部门但不是合同工的员工信息。

场景 2:多表数据对比
假设我们有三个表:top_rated_films、most_popular_films 和 highest_revenue_films,分别存储评分最高的电影、最受欢迎的电影和收入最高的电影。我们需要找出那些评分最高但既不是最受欢迎也不是收入最高的电影。

sql复制

SELECT film_id, title
FROM top_rated_films
EXCEPT
SELECT film_id, title
FROM most_popular_films
EXCEPT
SELECT film_id, title
FROM highest_revenue_films;
此查询通过多次使用 EXCEPT,从 top_rated_films 中排除了同时出现在 most_popular_films 和 highest_revenue_films 中的电影。

场景 3:数据去重与差异分析
假设我们有两个表 table1 和 table2,存储了相似的数据,但可能存在重复或差异。我们需要找出在 table1 中但不在 table2 中的记录。

sql复制

SELECT column1, column2
FROM table1
EXCEPT
SELECT column1, column2
FROM table2;
此查询返回 table1 中独有的记录,适用于数据去重和差异分析。

场景 4:多字段比较
假设我们有两个表 employees 和 departments,分别存储员工信息和部门信息。我们需要找出那些员工地址和电话与部门地址和电话不匹配的记录。

sql复制

SELECT address, phone
FROM employees
EXCEPT
SELECT address, phone
FROM departments;
此查询通过比较多个字段,返回 employees 表中与 departments 表不匹配的地址和电话记录。

总结
EXCEPT 是 PostgreSQL 中用于集合操作的强大工具,特别适用于以下场景:

在 PostgreSQL 中,EXCEPT 是一个集合操作符,它要求两个查询的结果集在结构上是完全一致的,即列的数量、数据类型和顺序必须完全匹配。如果表结构不同,EXCEPT 无法直接使用。

为什么表结构必须一致?
EXCEPT 的工作原理是基于集合的差集操作,它会逐行比较两个查询的结果集。如果列的数量、类型或顺序不一致,PostgreSQL 会抛出错误,因为无法确定如何进行比较。

例如,以下查询会失败:

sql复制

SELECT column1, column2
FROM table1
EXCEPT
SELECT column3, column4
FROM table2;
如果 column1 和 column3 的类型不同,或者 column2 和 column4 的顺序不一致,PostgreSQL 会报错。

如果表结构不同怎么办?
如果需要使用 EXCEPT,但表结构不同,可以通过以下方法解决:

方法 1:显式指定列名和数据类型
如果两个表的列名或数据类型不同,可以通过显式指定列名和转换数据类型来解决。例如:

sql复制

SELECT column1 AS common_column, column2 AS common_column2
FROM table1
EXCEPT
SELECT column3::same_data_type AS common_column, column4::same_data_type AS common_column2
FROM table2;
这里,我们通过重命名列(AS common_column)和转换数据类型(::same_data_type)来确保两个查询的结果集结构一致。

方法 2:使用子查询或临时表
如果表结构差异较大,可以通过子查询或临时表将数据转换为一致的格式。例如:

sql复制

WITH normalized_table1 AS (
SELECT column1 AS common_column, column2 AS common_column2
FROM table1
),
normalized_table2 AS (
SELECT column3 AS common_column, column4 AS common_column2
FROM table2
)
SELECT common_column, common_column2
FROM normalized_table1
EXCEPT
SELECT common_column, common_column2
FROM normalized_table2;
这里,我们通过公共表表达式(CTE)将两个表的数据转换为一致的格式,然后使用 EXCEPT 进行差集操作。

方法 3:使用其他方法(如 NOT EXISTS 或 NOT IN)
如果表结构差异太大,无法通过上述方法解决,可以考虑使用其他方法,如 NOT EXISTS 或 NOT IN。这些方法不要求表结构一致,但可能需要额外的逻辑来实现相同的功能。

例如:

sql复制

SELECT column1, column2
FROM table1
WHERE (column1, column2) NOT IN (
SELECT column3, column4
FROM table2
);
或者:

sql复制

SELECT column1, column2
FROM table1 t1
WHERE NOT EXISTS (
SELECT 1
FROM table2 t2
WHERE t1.column1 = t2.column3 AND t1.column2 = t2.column4
);
总结

在实际应用中,选择哪种方法取决于具体需求和表结构的差异。

在 PostgreSQL 中,NOT EXISTS、NOT IN 和 EXCEPT 都可以用于从结果集中排除某些记录,但它们在语法、功能、性能和适用场景上存在显著区别。以下是它们的详细对比:

  1. 语法和功能
    NOT EXISTS

SELECT column_name
FROM table_name t1
WHERE NOT EXISTS (
SELECT 1
FROM another_table t2
WHERE t1.some_column = t2.some_column
);

NOT IN

SELECT column_name
FROM table_name
WHERE some_column NOT IN (SELECT some_column FROM another_table);

EXCEPT

SELECT column_name
FROM table_name
EXCEPT
SELECT column_name
FROM another_table;

  1. 性能
    NOT EXISTS

NOT IN

EXCEPT

  1. 适用场景
    NOT EXISTS

NOT IN

EXCEPT

  1. 具体示例
    假设我们有两个表 employees 和 blacklist,需要找出不在黑名单中的员工。

使用 NOT EXISTS
sql复制

SELECT employee_id, name
FROM employees e
WHERE NOT EXISTS (
SELECT 1
FROM blacklist b
WHERE e.employee_id = b.employee_id
);

使用 NOT IN
sql复制

SELECT employee_id, name
FROM employees
WHERE employee_id NOT IN (SELECT employee_id FROM blacklist);

使用 EXCEPT
sql复制

SELECT employee_id, name
FROM employees
EXCEPT
SELECT employee_id, name
FROM employees
JOIN blacklist ON employees.employee_id = blacklist.employee_id;

  1. 总结

在实际应用中,可以根据具体需求、数据量和表结构选择合适的方法。

相关文章
|
3月前
|
存储 SQL 运维
速看!数据库与数据仓库的本质区别是什么?
本文深入解析了“数据库”与“数据仓库”的核心区别,涵盖设计目的、数据结构、使用场景、性能优化和数据更新五个维度。数据库主要用于支持实时业务操作,强调事务处理效率;数据仓库则面向企业分析决策,注重海量数据的整合与查询性能。二者在企业中各司其职,缺一不可。
|
4月前
|
存储 关系型数据库 MySQL
MySQL数据库中的 char 与 varchar的区别是什么
MySQL中的char和varchar均用于存储字符串,但有显著区别。char为定长类型,固定长度,存储空间始终为设定值,适合长度固定的数据如手机号。varchar为变长类型,仅占用实际数据所需空间,适合长度不固定的内容如用户名。二者在性能与空间利用上各有优劣,应根据实际场景合理选择。
396 0
|
存储 关系型数据库 MySQL
一个项目用5款数据库?MySQL、PostgreSQL、ClickHouse、MongoDB区别,适用场景
一个项目用5款数据库?MySQL、PostgreSQL、ClickHouse、MongoDB——特点、性能、扩展性、安全性、适用场景比较
|
9月前
|
SQL NoSQL Oracle
关系型与非关系型数据库的区别
关系型数据库是依据关系模型来创建的数据库,所谓关系模型就是“一对一”、“一对多”、“对多对”等。常见的关系型数据库有Oracle、MySQL、SQL Server等。非关系型数据库主要基于“非关系型模型”,其中非关系型模型有:列模型、键值对模型、文档类模型。比如redis属于键值对模型。 MongoDB属于文档模型 关系型数据库的优点: ● 易于维护:都是使用表结构,格式一致。 ● 使用方便:SQL语言通用,可用于复杂查询。 ● 复杂操作:支持SQL,可用于一个表以及多个表之间非常复杂的查询。 关系型数据库的缺点: ● 读写性能比较差,尤其是海量数据的高效率读写。 ● 固定的表结构,灵活
|
SQL 安全 网络安全
Web应用防火墙(WAF)与数据库应用防火墙有什么区别?
Web应用防火墙(WAF)专注于Web应用系统和网站的应用层防护,可有效应对OWASP Top 10等常见攻击,防止SQL注入、CC攻击等。而数据库应用防火墙则位于应用服务器与数据库之间,提供数据库访问控制、攻击阻断、虚拟补丁等高级防护功能,直接保护数据库免受攻击。两者分别针对Web层和数据库层提供不同的安全保护。
280 4
|
存储 SQL JSON
介绍一下RDBMS和NoSQL数据库之间的区别
【10月更文挑战第21天】介绍一下RDBMS和NoSQL数据库之间的区别
477 2
|
Oracle 关系型数据库 数据库
阿里云数据库 ACP 问题之阿里云数据库ACP认证与ACA认证有什么区别
阿里云数据库 ACP 问题之阿里云数据库ACP认证与ACA认证有什么区别
540 1
阿里云数据库 ACP 问题之阿里云数据库ACP认证与ACA认证有什么区别
|
SQL 关系型数据库 数据库连接
php连接数据库之PDO,PDO的简单使用和预定义占位符的使用以及PDOStatement对象的使用,占位符的不同形式,bindValue和bindParam绑定预定义占位符参数的区别
本文介绍了PHP中PDO(PHP Data Objects)扩展的基本概念和使用方法。内容包括PDO类和PDOStatement类的介绍,PDO的简单使用,预定义占位符的使用方法,以及PDOStatement对象的使用。文章还讨论了绑定预定义占位符参数的不同形式,即bindValue和bindParam的区别。通过具体示例,展示了如何使用PDO进行数据库连接、数据查询、数据插入等操作。
php连接数据库之PDO,PDO的简单使用和预定义占位符的使用以及PDOStatement对象的使用,占位符的不同形式,bindValue和bindParam绑定预定义占位符参数的区别
|
存储 安全 Java
springboot当中ConfigurationProperties注解作用跟数据库存入有啥区别
`@ConfigurationProperties`注解和数据库存储配置信息各有优劣,适用于不同的应用场景。`@ConfigurationProperties`提供了类型安全和模块化的配置管理方式,适合静态和简单配置。而数据库存储配置信息提供了动态更新和集中管理的能力,适合需要频繁变化和集中管理的配置需求。在实际项目中,可以根据具体需求选择合适的配置管理方式,或者结合使用这两种方式,实现灵活高效的配置管理。
203 0
|
存储 BI 数据库