一句话介绍
LEAST 就像是一个"选最小值"的小助手,给它一堆值,它就告诉你哪个最小!
sql
SELECT LEAST(3, 7, 2, 9, 5); -- 返回 2(最小的那个)
它和 GREATEST 是好兄弟,一个找最大,一个找最小!
基本语法
sql
LEAST(value1, value2, value3, ...)
通俗解释
- 输入:任意多个值(至少 2 个)
- 输出:这些值里面最小的那个
- 要求:所有值的类型要一样或兼容(比如都是数字,或者都是文本)
简单例子
sql
-- 找最小数字
SELECT LEAST(10, 20, 30); -- 返回 10
-- 找最小文本(按字母顺序)
SELECT LEAST('apple', 'banana', 'cherry'); -- 返回 'apple'
-- 找最早日期
SELECT LEAST('2024-01-01', '2024-06-15', '2024-03-20'); -- 返回 '2024-01-01'
核心特点(必看!)
特点 1:NULL 值是"捣蛋鬼"
重要规则:只要有一个值是 NULL,结果就是 NULL!
sql
SELECT LEAST(10, 20, NULL); -- 返回 NULL(因为有个 NULL)
SELECT LEAST(NULL, NULL); -- 返回 NULL
怎么办? 用 COALESCE 把 NULL 变成默认值:
sql
-- 把 NULL 当成 999 来处理(这样就不会被选中)
SELECT LEAST(COALESCE(price1, 999), COALESCE(price2, 999));
特点 2:类型必须一致
sql
-- ✅ 正确:都是数字
SELECT LEAST(10, 20.5, 30); -- 返回 10
-- ✅ 正确:都是文本
SELECT LEAST('A', 'B', 'C'); -- 返回 'A'
-- ❌ 错误:数字和文本混在一起
SELECT LEAST(10, 'hello'); -- 报错!
特点 3:文本比较是按字母顺序
sql
-- 字母越靠前,值越小
SELECT LEAST('apple', 'banana'); -- 返回 'apple'(a 在 b 前面)
-- 大写字母在小写前面(ASCII 码更小)
SELECT LEAST('A', 'a'); -- 返回 'A'
-- 中文按 Unicode 编码比较
SELECT LEAST('北京', '上海'); -- 取决于编码顺序
特点 4:可以有很多参数
sql
-- 不只两个,可以有任意多个
SELECT LEAST(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); -- 返回 1
常见使用场景(超实用!)
场景 1:找最低价格
假设你有个商品价格表,要从不同渠道找最低价:
sql
-- 表结构
CREATE TABLE product_prices (
product_name VARCHAR(50),
jd_price DECIMAL(10,2),
taobao_price DECIMAL(10,2),
pdd_price DECIMAL(10,2)
);
-- 插入数据
INSERT INTO product_prices VALUES
('iPhone 15', 7999.00, 7899.00, 7599.00),
('MacBook Pro', 14999.00, 14799.00, 14999.00),
('AirPods', 1299.00, 1199.00, 1099.00);
-- 找出每个商品的最低价格
SELECT
product_name,
jd_price,
taobao_price,
pdd_price,
LEAST(jd_price, taobao_price, pdd_price) AS lowest_price
FROM product_prices;
结果:
product_name | jd_price | taobao_price | pdd_price | lowest_price
-------------|----------|--------------|-----------|-------------
iPhone 15 | 7999.00 | 7899.00 | 7599.00 | 7599.00
MacBook Pro | 14999.00 | 14799.00 | 14999.00 | 14799.00
AirPods | 1299.00 | 1199.00 | 1099.00 | 1099.00
场景 2:设置最高限价
电商场景中,保证显示的价格不高于某个最高价:
sql
SELECT
product_name,
original_price,
LEAST(original_price, 9999) AS display_price -- 最高显示 9999
FROM products;
效果:即使原价是 19999 元,显示价格也不会超过 9999 元。
场景 3:优惠券使用(选最优惠)
sql
SELECT
order_id,
coupon_discount, -- 优惠券折扣
member_discount, -- 会员折扣
promotion_discount, -- 促销折扣
LEAST(coupon_discount, member_discount, promotion_discount) AS best_discount
FROM orders;
效果:自动选择最优惠的折扣方式(折扣值最小的)。
场景 4:找最早的日期
sql
SELECT
order_id,
order_date,
payment_date,
shipping_date,
LEAST(order_date, payment_date, shipping_date) AS earliest_date
FROM orders;
用途:找出订单流程中最早的操作时间。
场景 5:库存预警
sql
-- 找出库存最低的仓库
SELECT
product_name,
warehouse_a_stock,
warehouse_b_stock,
warehouse_c_stock,
LEAST(warehouse_a_stock, warehouse_b_stock, warehouse_c_stock) AS min_stock
FROM inventory;
场景 6:多来源评分取最低
sql
-- 从三个不同的质检系统中取最低分(最严格的标准)
SELECT
product_id,
quality_check_1,
quality_check_2,
quality_check_3,
LEAST(quality_check_1, quality_check_2, quality_check_3) AS final_quality_score
FROM quality_reports;
场景 7:阶梯用量计算
sql
-- 根据不同条件计算最终用量,确保不超过配额
SELECT
user_id,
requested_usage,
monthly_quota,
LEAST(requested_usage, monthly_quota) AS approved_usage -- 不超过配额
FROM user_requests;
高级用法
1. 与 CASE 结合使用
sql
-- 根据用户等级应用不同的最高消费限制
SELECT
user_name,
total_spent,
CASE user_level
WHEN 'VIP' THEN LEAST(total_spent, 10000) -- VIP 最高 10000
WHEN 'Gold' THEN LEAST(total_spent, 5000) -- 金卡最高 5000
ELSE LEAST(total_spent, 1000) -- 普通用户最高 1000
END AS capped_amount
FROM users;
2. 与 COALESCE 配合处理 NULL
sql
-- 安全地找最小值,NULL 当作很大值处理(这样就不会被选中)
SELECT
product_name,
LEAST(
COALESCE(price_a, 999999),
COALESCE(price_b, 999999),
COALESCE(price_c, 999999)
) AS lowest_price
FROM products;
3. 在 UPDATE 中使用
sql
-- 更新最高工资限制
UPDATE employees
SET salary = LEAST(salary, 50000) -- 工资高于 50000 的降到 50000
WHERE department = 'Management';
4. 在 ORDER BY 中使用
sql
-- 按最低分排序
SELECT * FROM students
ORDER BY LEAST(math_score, english_score, science_score) ASC;
5. 与聚合函数结合
sql
-- 每个班级的最低单科平均分
SELECT
class_id,
MIN(LEAST(math_avg, english_avg, science_avg)) AS class_worst_score
FROM class_statistics
GROUP BY class_id;
LEAST vs GREATEST(好兄弟对比)
PostgreSQL 有两个相反的函数:
| 函数 | 作用 | 例子 | 结果 |
|---|---|---|---|
| LEAST | 找最小值 | LEAST(3, 7, 2) |
2 |
| GREATEST | 找最大值 | GREATEST(3, 7, 2) |
7 |
实际对比
sql
-- 同时使用两个函数
SELECT
price,
LEAST(price, 100) AS max_price, -- 确保不高于 100
GREATEST(price, 10) AS min_price, -- 确保不低于 10
LEAST(GREATEST(price, 10), 100) AS bounded_price -- 限制在 10-100 之间
FROM products;
效果:把价格限制在 10 到 100 元之间!
实际应用示例(完整案例)
案例 1:电商平台最优价格推荐
sql
-- 场景:为用户推荐最便宜的购买方案
-- 规则:
-- 1. 比较自营、第三方、二手的价格
-- 2. 考虑运费
-- 3. 显示总价最低的方案
SELECT
product_name,
-- 自营价格(含运费)
self_operated_price + self_operated_shipping AS self_total,
-- 第三方价格(含运费)
third_party_price + third_party_shipping AS third_total,
-- 二手价格(含运费)
used_price + used_shipping AS used_total,
-- 推荐最低总价
LEAST(
self_operated_price + self_operated_shipping,
third_party_price + third_party_shipping,
used_price + used_shipping
) AS recommended_price,
-- 推荐购买渠道
CASE
WHEN LEAST(
self_operated_price + self_operated_shipping,
third_party_price + third_party_shipping,
used_price + used_shipping
) = self_operated_price + self_operated_shipping
THEN '自营'
WHEN LEAST(
self_operated_price + self_operated_shipping,
third_party_price + third_party_shipping,
used_price + used_shipping
) = third_party_price + third_party_shipping
THEN '第三方'
ELSE '二手'
END AS recommended_channel
FROM product_listings;
案例 2:员工考勤系统
sql
-- 场景:计算员工最早打卡时间
-- 规则:
-- 1. 可能有多个打卡记录(门禁、APP、指纹)
-- 2. 取最早的作为上班时间
-- 3. NULL 表示未打卡
SELECT
employee_id,
employee_name,
work_date,
-- 各种打卡方式的时间
door_access_time,
app_checkin_time,
fingerprint_time,
-- 最早打卡时间(NULL 用很晚的时间替代,这样不会被选中)
LEAST(
COALESCE(door_access_time, '23:59:59'),
COALESCE(app_checkin_time, '23:59:59'),
COALESCE(fingerprint_time, '23:59:59')
) AS actual_checkin_time,
-- 是否迟到(假设 9:00 上班)
CASE
WHEN LEAST(
COALESCE(door_access_time, '23:59:59'),
COALESCE(app_checkin_time, '23:59:59'),
COALESCE(fingerprint_time, '23:59:59')
) > '09:00:00'
THEN '迟到'
ELSE '正常'
END AS attendance_status
FROM attendance_records;
案例 3:物流配送优化
sql
-- 场景:选择最快的配送方式
-- 规则:
-- 1. 比较快递、物流、自提的时间
-- 2. 选择耗时最短的
-- 3. 考虑成本上限
SELECT
order_id,
destination,
-- 各种配送方式的预计天数
express_delivery_days,
standard_shipping_days,
pickup_days,
-- 最快配送时间
LEAST(express_delivery_days, standard_shipping_days, pickup_days) AS fastest_days,
-- 推荐配送方式
CASE
WHEN LEAST(express_delivery_days, standard_shipping_days, pickup_days) = express_delivery_days
THEN '快递'
WHEN LEAST(express_delivery_days, standard_shipping_days, pickup_days) = standard_shipping_days
THEN '物流'
ELSE '自提'
END AS recommended_method,
-- 对应的费用
CASE
WHEN LEAST(express_delivery_days, standard_shipping_days, pickup_days) = express_delivery_days
THEN express_cost
WHEN LEAST(express_delivery_days, standard_shipping_days, pickup_days) = standard_shipping_days
THEN standard_cost
ELSE pickup_cost
END AS estimated_cost
FROM delivery_options;
案例 4:学生考试补考安排
sql
-- 场景:确定学生需要补考的科目
-- 规则:
-- 1. 三科中任一科不及格就需要补考
-- 2. 显示最低分数
-- 3. 标记是否需要补考
SELECT
student_id,
student_name,
math_score,
english_score,
science_score,
-- 最低分数
LEAST(math_score, english_score, science_score) AS lowest_score,
-- 是否需要补考
CASE
WHEN LEAST(math_score, english_score, science_score) < 60
THEN '需要补考'
ELSE '通过'
END AS exam_status,
-- 需要补考的科目
CASE
WHEN math_score = LEAST(math_score, english_score, science_score) AND math_score < 60
THEN '数学'
WHEN english_score = LEAST(math_score, english_score, science_score) AND english_score < 60
THEN '英语'
WHEN science_score = LEAST(math_score, english_score, science_score) AND science_score < 60
THEN '科学'
ELSE '无'
END AS retake_subject
FROM exam_results;
性能小贴士
✅ 好的做法
sql
-- LEAST 很快,放心用
SELECT LEAST(col1, col2, col3) FROM table;
-- 参数少的时候特别快
SELECT LEAST(price, max_price) FROM products;
⚠️ 注意事项
sql
-- 太多参数可能影响可读性(虽然性能没问题)
-- ❌ 不推荐:参数太多,难以阅读
SELECT LEAST(a, b, c, d, e, f, g, h, i, j) FROM table;
-- ✅ 推荐:分成多次或使用其他方法
SELECT LEAST(
LEAST(a, b, c),
LEAST(d, e, f),
LEAST(g, h, i, j)
) FROM table;
常见错误和解决方案
错误 1:NULL 导致结果为 NULL
sql
-- ❌ 问题
SELECT LEAST(10, 20, NULL); -- 返回 NULL
-- ✅ 解决
SELECT LEAST(10, 20, COALESCE(NULL, 999)); -- 返回 10
错误 2:类型不匹配
sql
-- ❌ 问题
SELECT LEAST(10, '20'); -- 报错!
-- ✅ 解决
SELECT LEAST(10, 20::INT); -- 返回 10
SELECT LEAST(10::TEXT, '20'); -- 返回 '10'
错误 3:忘记至少需要两个参数
sql
-- ❌ 问题
SELECT LEAST(10); -- 报错!
-- ✅ 解决
SELECT LEAST(10, 999); -- 返回 10
错误 4:文本比较不符合预期
sql
-- ❌ 以为会返回 '10'(数值最小)
SELECT LEAST('9', '100'); -- 返回 '100'(因为 '1' < '9')
-- ✅ 如果要按数值比较,先转换类型
SELECT LEAST('9'::INT, '100'::INT); -- 返回 9
最佳实践总结
🎯 什么时候用 LEAST?
- 需要上限值:确保不高于某个最大值
- 多选一取最小:从多个值中选最小的
- 数据修正:把异常值(如超大值)修正为合理值
- 价格控制:设置价格上限
- 最优选择:找最便宜、最快、最早的选项
💡 使用技巧
sql
-- 技巧 1:设置范围(配合 GREATEST)
LEAST(GREATEST(value, min_value), max_value)
-- 技巧 2:处理 NULL(用大值替代)
LEAST(COALESCE(value1, 999999), COALESCE(value2, 999999))
-- 技巧 3:条件上限
LEAST(calculated_value, maximum_threshold)
📝 代码规范
sql
-- ✅ 好的写法:清晰的注释
SELECT
LEAST(price, retail_price) AS final_price -- 确保不高于零售价
FROM products;
-- ✅ 好的写法:合理的格式化
SELECT LEAST(
member_price,
vip_price,
regular_price
) AS best_price
FROM products;
快速参考卡片
┌─────────────────────────────────────┐
│ LEAST 函数速查表 │
├─────────────────────────────────────┤
│ 功能:返回最小值 │
│ │
│ 语法:LEAST(v1, v2, v3, ...) │
│ │
│ 特点: │
│ • NULL 会导致结果为 NULL │
│ • 类型必须一致 │
│ • 至少需要 2 个参数 │
│ │
│ 常用场景: │
│ • 设置最高值(封顶) │
│ • 多值选最小 │
│ • 数据修正 │
│ • 价格控制 │
│ • 最优选择(最便宜/最快) │
│ │
│ 黄金组合: │
│ • LEAST + COALESCE(处理NULL) │
│ • LEAST + GREATEST(设置范围) │
└─────────────────────────────────────┘
常见问题 FAQ
Q1: LEAST 和 MIN 有什么区别?
A:
LEAST:比较同一行的多个列/值MIN:比较不同行的同一个列
sql
-- LEAST:横向比较(同一行)
SELECT LEAST(math, english, science) FROM students;
-- MIN:纵向比较(不同行)
SELECT MIN(math) FROM students;
Q2: 如果所有值都是 NULL 怎么办?
A: 结果就是 NULL。如果想避免,用 COALESCE:
sql
SELECT COALESCE(LEAST(a, b, c), 0) FROM table;
Q3: 可以比较日期吗?
A: 当然可以!日期也可以比较大小:
sql
SELECT LEAST('2024-01-01', '2024-06-15'); -- 返回 '2024-01-01'
Q4: 性能怎么样?
A: 非常快!LEAST 是内置函数,几乎没性能开销。
Q5: 最多可以有多少个参数?
A: PostgreSQL 没有严格限制,但建议不超过 20-30 个,否则影响可读性。
Q6: LEAST 和 GREATEST 能嵌套使用吗?
A: 当然可以!这是设置范围的经典用法:
sql
-- 把值限制在 10 到 100 之间
SELECT LEAST(GREATEST(value, 10), 100) FROM table;
总结
LEAST 就是一个"选最小值"的实用工具:
✨ 简单易用 :给它一堆值,它返回最小的
🛡️ 数据安全 :可以设置上限值,防止异常数据
🎯 灵活多变 :可以和很多函数配合使用
⚡ 性能优秀:内置函数,速度飞快
记住三个要点:
- NULL 会让结果变 NULL(用 COALESCE 解决)
- 类型要一致(数字、文本、日期各自比较)
- 常和 GREATEST 配合设置范围
经典用法:
sql
-- 封顶机制
LEAST(value, maximum_value)
-- 范围限制
LEAST(GREATEST(value, min), max)
-- 处理 NULL
LEAST(COALESCE(a, 999), COALESCE(b, 999))
与 GREATEST 的配合:
sql
-- 完美组合:设置上下限
LEAST(GREATEST(price, 10), 100) -- 价格在 10-100 之间
用好 LEAST,让你的 SQL 查询更健壮、更安全!它和 GREATEST 是一对好兄弟,经常一起出现,帮你轻松处理各种边界值问题。