数据库中的EXISTS

前言

EXISTS 和 NOT EXISTS 是 SQL 中用于存在性判断的谓词,返回布尔值(TRUE/FALSE),常用于 WHERE 子句中过滤数据

使用

准备两张表

sql 复制代码
-- public.campus_device definition

  


-- Drop table

  


-- DROP TABLE public.campus_device;

  


CREATE TABLE public.campus_device (

id int8 NOT NULL,

create_id int8 NULL,

create_time timestamp NULL,

dr int4 NULL,

last_modify_id int8 NULL,

last_modify_time timestamp NULL,

tenant_id int8 NULL,

"version" int4 NULL,

device_name varchar(255) NULL,

mac varchar(255) NULL,

org_id int8 NULL,

product_id int8 NULL,

saas_device_id int8 NULL,

verify_code varchar(255) NULL,

address varchar(255) DEFAULT NULL::character varying NULL,

createid int8 NULL,

devicename varchar(255) NULL,

orgid int8 NULL,

productid int8 NULL,

saasdeviceid int8 NULL,

verifycode varchar(255) NULL,

CONSTRAINT campus_device_pkey PRIMARY KEY (id)

);

以及

sql 复制代码
-- public.campus_room_user_rel definition

  


-- Drop table

  


-- DROP TABLE public.campus_room_user_rel;

  


CREATE TABLE public.campus_room_user_rel (

id int8 NOT NULL,

room_id int8 NULL,

user_id int8 NULL,

create_id int8 NULL,

create_time timestamp DEFAULT CURRENT_TIMESTAMP NULL,

last_modify_id int8 NULL,

last_modify_time timestamp NULL,

"version" int4 DEFAULT 0 NULL,

dr int4 DEFAULT 0 NULL,

tenant_id int8 NULL,

admin_status varchar NULL,

user_authored_type varchar NULL,

createid int8 NULL,

adminstatus varchar(255) NULL,

roomid int8 NULL,

userauthoredtype varchar(255) NULL,

userid int8 NULL,

bed_number int4 NULL,

CONSTRAINT campus_room_user_rel_pkey PRIMARY KEY (id)

);

语法使用

sql 复制代码
-- EXISTS:子查询有结果返回 TRUE 

SELECT * FROM 表A WHERE EXISTS (SELECT 1 FROM 表B WHERE 表B.id = 表A.id);

-- NOT EXISTS:

子查询无结果返回 TRUE

SELECT * FROM 表A WHERE NOT EXISTS (SELECT 1 FROM 表B WHERE 表B.id = 表A.id);

核心特点

只关心"有没有",不关心"是什么":子查询中写 SELECT 1、SELECT * 或 SELECT 字段名 效果完全一样,因为 EXISTS 只判断是否返回了行,不关心具体返回值。

短路评估:找到第一条匹配记录就立即停止扫描,性能优于 COUNT(*) > 0。

相关子查询:子查询通常依赖外层查询的字段做关联条件,对外层每一行都会执行一次子查询。 执行流程

以 NOT EXISTS 为例:

外层查询取出一行记录

将该行字段值代入子查询执行

子查询返回空集 → NOT EXISTS 为 TRUE → 该行保留

子查询返回至少一行 → NOT EXISTS 为 FALSE → 该行过滤掉

重复以上步骤直到外层遍历完

与 NOT IN 的关键区别

表对比维度 NOT EXISTS NOT IN
NULL 处理 不受 NULL 影响,安全 子查询含 NULL 时整个条件可能返回空集
执行方式 逐行检查,找到即停 需先加载完整子查询结果集再逐一比对
性能 通常更优,尤其大数据量场景 子查询结果集大时可能全表扫描
⚠️ 如果子查询字段允许 NULL 且未加 IS NOT NULL 过滤,禁止使用 NOT IN,必须用 NOT EXISTS。
常见应用场景
查找有关联数据的记录(EXISTS):如"查询有订单的客户"
查找没有关联数据的记录(NOT EXISTS):如"查询未分配班级的学生"
防重复插入:插入前判断记录是否已存在
替代 COUNT(*) > 0 做存在性判断

语法查询

sql 复制代码
SELECT c.*

FROM campus_room c

WHERE c.tenant_id = 2031967244505841665

AND c.dr = 0

AND NOT EXISTS (

SELECT 1

FROM campus_room_user_rel l

WHERE l.room_id = c.id and l.dr = 0

);

  


select * from campus_room c where c.id= 2075450553046925314 and

exists (select 1 from campus_room_user_rel u where c.id = u.room_id );

总结

数据库中的EXISTSnot EXISTS在某种情况下查询更优

相关推荐
Wang's Blog1 小时前
Java框架快速入门: Spring Security+OAuth2之数据库和实体类的RBAC改造
java·数据库·spring
郑州光合科技余经理2 小时前
国际版外卖系统:税率字段怎么和订单主流程解耦
android·java·开发语言·前端·后端·php·ai编程
毅炼2 小时前
Rover-Suite 开源发布:轻量服务注册中心与网关一体化方案
java·后端·系统架构·gateway
梦想平凡2 小时前
百游棋牌源代码开发搭建教程(十):隔离部署、备份恢复与双端验收
java·前端·javascript·数据库·源代码管理
xcLeigh3 小时前
让大模型长出手脚,自己写SQL查数据库(Function Calling初探)
数据库·人工智能·sql·时序数据库·timechoai
天远数科3 小时前
零信任架构实战:基于天远全能消金报告构建自动化信贷评估网关
运维·人工智能·架构·自动化
yume_sibai4 小时前
06-Rust Web 开发实战(Axum 框架 + 数据库 + JWT 认证 + 中间件 + 部署)
前端·数据库·rust
AugustRed5 小时前
Neo4j 图数据库原理 + 应用场景简单介绍
数据库·neo4j
Gl�ria5 小时前
Redis 高可用架构对比
数据库·redis