MySQL条件判断函数
条件判断函数是MySQL中用于根据条件返回不同结果的函数。这些函数在SQL查询中非常有用,可以用于数据转换、条件筛选和结果格式化等场景。MySQL提供了多种条件判断函数,包括IF函数、IFNULL函数和CASE函数等。
IF(expr, v1, v2)函数
IF函数根据条件表达式expr的结果返回v1或v2:
- 如果expr为TRUE(expr <> 0且expr <> NULL),则返回v1
- 如果expr为FALSE(expr = 0或expr = NULL),则返回v2
IF函数示例
-- 基本用法:判断学生分数是否及格
SELECT student_name, score, IF(score >= 60, '及格', '不及格') AS result
FROM students;
-- 嵌套IF函数:根据分数划分等级
SELECT student_name, score,
IF(score >= 90, '优秀',
IF(score >= 80, '良好',
IF(score >= 60, '及格', '不及格'))) AS grade
FROM students;
-- 在UPDATE语句中使用IF
UPDATE products
SET stock = IF(stock > 0, stock - 1, 0)
WHERE product_id = 123;
-- 计算两个数的最大值
SELECT a, b, IF(a > b, a, b) AS max_value
FROM numbers;
IFNULL(v1, v2)函数
IFNULL函数用于处理NULL值:
- 如果v1不为NULL,则返回v1
- 如果v1为NULL,则返回v2
IFNULL函数示例
-- 处理NULL值,将NULL替换为0
SELECT product_name, IFNULL(stock, 0) AS available_stock
FROM products;
-- 计算平均成绩,处理NULL值
SELECT AVG(IFNULL(score, 0)) AS average_score
FROM exam_results;
-- 在字符串拼接中使用IFNULL
SELECT CONCAT(first_name, ' ', IFNULL(middle_name, ''), ' ', last_name) AS full_name
FROM employees;
-- 计算总销售额,处理NULL值
SELECT SUM(IFNULL(amount, 0)) AS total_sales
FROM orders;
CASE函数
CASE函数是一种更复杂的条件表达式,可以包含多个条件分支:
CASE函数有两种语法形式:
形式一:简单CASE函数
CASE expression
WHEN value1 THEN result1
WHEN value2 THEN result2
...
ELSE resultN
END
形式二:搜索CASE函数
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
...
ELSE resultN
END
CASE函数示例
-- 简单CASE函数示例:根据部门ID显示部门名称
SELECT employee_id, employee_name, department_id,
CASE department_id
WHEN 1 THEN '人力资源部'
WHEN 2 THEN '财务部'
WHEN 3 THEN '技术部'
WHEN 4 THEN '市场部'
ELSE '其他部门'
END AS department_name
FROM employees;
-- 搜索CASE函数示例:根据分数划分等级
SELECT student_name, score,
CASE
WHEN score >= 90 THEN '优秀'
WHEN score >= 80 THEN '良好'
WHEN score >= 70 THEN '中等'
WHEN score >= 60 THEN '及格'
ELSE '不及格'
END AS grade
FROM students;
-- 在分组查询中使用CASE函数
SELECT
CASE
WHEN age < 18 THEN '未成年'
WHEN age BETWEEN 18 AND 60 THEN '成年人'
ELSE '老年人'
END AS age_group,
COUNT(*) AS count
FROM users
GROUP BY age_group;
-- 计算不同状态的订单数量
SELECT
SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) AS pending_orders,
SUM(CASE WHEN status = 'processing' THEN 1 ELSE 0 END) AS processing_orders,
SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) AS completed_orders,
SUM(CASE WHEN status = 'cancelled' THEN 1 ELSE 0 END) AS cancelled_orders
FROM orders;
-- 使用CASE函数进行数据透视
SELECT
product_id,
MAX(CASE WHEN month = 'Jan' THEN sales ELSE 0 END) AS Jan_sales,
MAX(CASE WHEN month = 'Feb' THEN sales ELSE 0 END) AS Feb_sales,
MAX(CASE WHEN month = 'Mar' THEN sales ELSE 0 END) AS Mar_sales
FROM sales_data
GROUP BY product_id;
提示:在MySQL中,CASE函数可以用于SELECT、WHERE、ORDER BY、GROUP BY等子句中,也可以用于UPDATE、DELETE语句中。它是一种非常灵活的条件判断工具,可以替代多层嵌套的IF函数,使代码更清晰易读。
NULL值处理的函数
除了IFNULL函数外,MySQL还提供了其他处理NULL值的函数:
函数 | 描述 | 示例 |
---|---|---|
ISNULL(expr) | 检查expr是否为NULL,如果是则返回1,否则返回0 | ISNULL(NULL) = 1,ISNULL('hello') = 0 |
NULLIF(expr1, expr2) | 如果expr1等于expr2,则返回NULL,否则返回expr1 | NULLIF(5, 5) = NULL,NULLIF(5, 3) = 5 |
COALESCE(expr1, expr2, ...) | 返回参数列表中的第一个非NULL值 | COALESCE(NULL, 'a', 'b') = 'a' |
NULL值处理函数示例
-- ISNULL函数示例
SELECT product_name, price, ISNULL(price) AS is_price_null
FROM products;
-- NULLIF函数示例:避免除零错误
SELECT a, b, NULLIF(b, 0) AS safe_divisor,
CASE WHEN b = 0 THEN NULL ELSE a / b END AS result
FROM numbers;
-- COALESCE函数示例:按优先级选择联系人方式
SELECT customer_id, customer_name,
COALESCE(email, phone, 'No contact info') AS contact_info
FROM customers;
-- 组合使用NULL值处理函数
SELECT product_id, product_name,
COALESCE(IFNULL(discount_price, price), 0) AS final_price
FROM products;
条件判断函数的高级应用
条件判断函数可以与其他函数结合使用,实现更复杂的逻辑:
高级应用示例
-- 计算客户的VIP等级
SELECT customer_id, customer_name, total_spent,
CASE
WHEN total_spent >= 10000 THEN '钻石VIP'
WHEN total_spent >= 5000 THEN '黄金VIP'
WHEN total_spent >= 1000 THEN '白银VIP'
ELSE '普通客户'
END AS vip_level,
-- 根据VIP等级计算折扣
CASE
WHEN total_spent >= 10000 THEN 0.8
WHEN total_spent >= 5000 THEN 0.9
WHEN total_spent >= 1000 THEN 0.95
ELSE 1.0
END AS discount_rate
FROM customer_orders;
-- 统计每月销售额,并计算同比增长
SELECT
year, month, sales,
LAG(sales, 12) OVER (ORDER BY year, month) AS prev_year_sales,
CASE
WHEN LAG(sales, 12) OVER (ORDER BY year, month) IS NULL THEN NULL
ELSE ROUND((sales - LAG(sales, 12) OVER (ORDER BY year, month)) / LAG(sales, 12) OVER (ORDER BY year, month) * 100, 2)
END AS yoy_growth_rate
FROM monthly_sales;
-- 使用条件函数实现复杂的排序
SELECT product_name, category, price, stock
FROM products
ORDER BY
-- 首先按类别排序
category,
-- 然后按价格和库存综合排序
CASE
WHEN stock = 0 THEN 2 -- 无库存的排在最后
WHEN price > 1000 THEN 0 -- 高价值商品优先
ELSE 1 -- 其他商品
END,
price DESC;
-- 使用条件函数进行动态列选择
SET @column_name = 'price';
SELECT
product_id,
product_name,
CASE @column_name
WHEN 'price' THEN price
WHEN 'stock' THEN stock
WHEN 'sales' THEN sales
ELSE 0
END AS selected_value
FROM products;