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;