PostGresql All语法
in语法(摆在这里用于对比)
-- 检查是否在值列表中
SELECT * FROM products WHERE price IN (100, 200, 300);-- 检查是否在子查询结果中
SELECT * FROM employees
WHERE salary IN (SELECT salary FROM managers WHERE level = 'Senior');
all语法
1、支持复杂的比较逻辑
-- 与比较运算符结合使用
SELECT * FROM products WHERE price > ALL(ARRAY[100, 200, 300]);-- 子查询形式
SELECT * FROM employees
WHERE salary > ALL(SELECT salary FROM junior_employees);-- ALL 可以配合各种比较运算符
SELECT * FROM students WHERE score >= ALL(ARRAY[60, 70, 80]); -- 分数大于等于所有阈值
SELECT * FROM products WHERE price < ALL(ARRAY[100, 200, 300]); -- 价格小于所有参考值
SELECT * FROM orders WHERE quantity <> ALL(ARRAY[0, 10, 20]); -- 数量不等于任何排除值-- IN 只能做等值比较,无法实现上述逻辑
2、处理范围查询更直观
-- 查找工资高于所有初级员工的员工
SELECT name, salary FROM employees
WHERE salary > ALL(SELECT salary FROM employees WHERE level = 'Junior'
);-- 用 IN 无法直接实现,需要子查询 + 聚合
SELECT name, salary FROM employees
WHERE salary > (SELECT MAX(salary) FROM employees WHERE level = 'Junior');
3、避免 NOT IN 的 NULL 值陷阱
-- NOT IN 的潜在问题
SELECT * FROM users WHERE id NOT IN (1, 2, NULL);
-- 这总是返回空结果,因为 NOT IN 遇到 NULL 会返回未知-- 使用 ALL 安全替代
SELECT * FROM users WHERE id <> ALL(ARRAY[1, 2, NULL]);
-- 这会正常返回不符合条件的记录
4、与数组操作更紧密集成
-- 动态数组处理
CREATE OR REPLACE FUNCTION find_products_above_threshold(thresholds integer[])
RETURNS SETOF products AS $$
BEGINRETURN QUERY SELECT * FROM products WHERE price > ALL(thresholds);
END;
$$ LANGUAGE plpgsql;-- 调用函数
SELECT * FROM find_products_above_threshold(ARRAY[100, 150, 200]);
all/in性能对比
场景 1:大型数据集
-- ALL 配合子查询(通常更高效)
EXPLAIN ANALYZE
SELECT * FROM large_table
WHERE value > ALL(SELECT threshold FROM thresholds WHERE category = 'A');-- 等效的 IN + 聚合(可能更慢)
EXPLAIN ANALYZE
SELECT * FROM large_table
WHERE value > (SELECT MAX(threshold) FROM thresholds WHERE category = 'A');
场景 2:复杂条件链
-- 使用 ALL 的清晰写法
SELECT * FROM sensor_data
WHERE temperature > ALL(ARRAY[20, 25, 30])AND humidity < ALL(ARRAY[80, 85, 90]);-- 等效的 AND 链(更冗长)
SELECT * FROM sensor_data
WHERE temperature > 20 AND temperature > 25 AND temperature > 30AND humidity < 80 AND humidity < 85 AND humidity < 90;
案例应用
案例 1:学生成绩分析
-- 找出在所有科目中都及格的学生
SELECT student_id, name
FROM students
WHERE 60 <= ALL(SELECT score FROM scores WHERE scores.student_id = students.student_id
);-- 比使用多个 EXISTS 或 MIN() 更简洁
案例 2:库存管理
-- 找出库存量低于所有仓库安全库存的产品
SELECT product_id, product_name
FROM products p
WHERE p.current_stock < ALL(SELECT safety_stock FROM warehouses WHERE product_id = p.product_id
);
案例 3:价格策略分析
-- 找出价格低于所有竞争对手的产品
SELECT our_products.*
FROM our_products
WHERE price < ALL(SELECT competitor_price FROM competitor_prices WHERE product_category = our_products.category
);
场景
适合使用 ALL 的场景:
-
✅ 需要与多个值进行比较运算时
-
✅ 处理动态的阈值数组时
-
✅ 需要避免 NOT IN 的 NULL 问题时
-
✅ 子查询返回多个值需要比较时
适合使用 IN 的场景:
-
✅ 简单的等值成员检查时
-
✅ 固定的值列表时
-
✅ 可读性优先的简单查询时
