数据库中的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 );

总结

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

相关推荐
脚本自动化开发4 小时前
玩影之刃零,两张四千元级显卡怎么挑
后端
OceanRoy5 小时前
数据库表的设计
数据库·内连接·外连接·er图·表的约束·三大范式·多表连接
Pniubi6 小时前
怎么排查慢SQL,怎么解决?
java·数据库·sql
用户47949283569157 小时前
从一句话或代码仓到可交互 HTML:开源 Agent 画图技能 Archify v3.2 实测与选型边界
前端·后端·面试
努力的小雨8 小时前
别再复制日志给AI了!我让Codex自己去观测云查报错
后端
Decay__10 小时前
VMware 安装 SQL Server 双节点 AlwaysOn 可用性组教程 —— WSFC、AG 与侦听器完整部署(系列核心篇)
运维·数据库·sql·mysql·架构
测试界的小码农10 小时前
【Linux 命令实战(06):Linux 文件权限管理,掌握 chmod、chown、chgrp】
linux·运维·服务器
afumu10 小时前
Go 写一个只监听 127.0.0.1 的控制服务:鉴权、白名单、危险命令拦截
后端·安全·go
茶栀(*´I`*)11 小时前
SQL 性能分析:从慢查询日志到执行计划的完整定位方法
数据库·sql
艺杯羹11 小时前
1Panel 装好后 ufw 仍是 inactive:一次服务器安全盲区复盘
服务器·数据库·安全·网络安全·系统架构·实战·1panel