every 是 bool_and 的完全等价别名,语义、结果与执行计划均一致;其 null 处理遵循“不否定”逻辑,聚合中不可用于 where,须配合 group by/having 使用,且无匹配行时返回 null。

EVERY 是 BOOL_AND 的完全等价物,别名而已
PostgreSQL 中 EVERY 不是独立实现的函数,它就是 BOOL_AND 的 SQL 标准别名。执行 SELECT EVERY(flag) 和 SELECT BOOL_AND(flag) 在语义、结果、执行计划上完全一致——连源码里都是同一个函数入口。你选哪个纯看团队风格或 SQL 标准兼容需求(比如对接某些 BI 工具时更认 EVERY)。
NULL 值处理逻辑必须心里有数
EVERY 对 NULL 的处理不是“跳过”,而是“不否定”:只要所有非-NULL 值都为 true,结果就是 true;只要有一个 false,结果就是 false;如果全为 NULL 或混合 NULL + true,结果是 NULL。
EVERY(ARRAY[true, true, NULL]) → trueEVERY(ARRAY[true, false, NULL]) → falseEVERY(ARRAY[NULL, NULL]) → NULL
这和 AND 运算符行为一致,但容易误以为 NULL 被忽略。实际在聚合中,NULL 是参与逻辑判定的“未知态”,不是空值过滤项。
WHERE 子句里用 EVERY 没有意义,也根本不能用
EVERY 是聚合函数,只能出现在 SELECT 列表或 HAVING 子句中,**不能用于 WHERE**。常见错误是想写:WHERE EVERY(status = 'active')——这会直接报错 syntax error at or near "EVERY"。
真正该做的,是把条件下推到行级:
PostgreSQL 18.4 官方 Ubuntu 安装包现已发布,这是目前最新的稳定版本。推荐通过官方 APT 仓库安装:先执行 sudo apt update 更新索引,再运行 sudo apt install postgresql-18 即可完成部署。新版本引入了异步 I/O 子系统,在顺序扫描与 VACUUM 场景下性能提升显著,同时支持 UUID v7 原生生成函数与虚拟生成列。
- 要查“所有用户状态都是 active”的分组?→ 用
GROUP BY dept_id HAVING EVERY(status = 'active') - 要查“某个部门所有成员都 active”?→ 先
GROUP BY dept_id,再HAVING - 只是过滤单行?→ 直接写
WHERE status = 'active',别碰EVERY
和 FILTER 配合时默认返回 NULL,得主动兜底
用 FILTER 限定范围后,EVERY 仍遵循聚合函数通用规则:无匹配行时返回 NULL,不是 true 或 false。
例如:EVERY(is_verified) FILTER (WHERE role = 'admin') 在某个分组里没有 admin 用户时,结果是 NULL,而非你想当然的 true(“没人是 admin,所以默认满足?”)。
安全写法是显式处理:COALESCE(EVERY(is_verified) FILTER (WHERE role = 'admin'), true)——但注意:这个 true 是业务语义,默认“无人即满足”,不是数据库逻辑。
真正容易被忽略的是:EVERY 的计算不可并行(截至 PostgreSQL 16),且一旦嵌套在复杂 CASE 或子查询里,优化器很可能放弃下推 WHERE 条件,导致全表扫描。别为了语法简洁牺牲可推导性。










