-- 简单CASE SELECT product_name, CASE category WHEN'Electronics'THEN'Tech' WHEN'Clothing'THEN'Fashion' ELSE'Other' ENDAS simplified_category FROM products;
-- 搜索CASE SELECT product_name, price, CASE WHEN price <50THEN'Budget' WHEN price <100THEN'Mid-range' WHEN price <200THEN'Premium' ELSE'Luxury' ENDAS price_range FROM products;
五、聚合函数
1. 基本聚合函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
-- 计算总数 SELECTCOUNT(*) FROM orders;
-- 计算非NULL值总数 SELECTCOUNT(shipping_address) FROM orders;
-- 求和 SELECTSUM(total_amount) FROM orders;
-- 平均值 SELECTAVG(total_amount) FROM orders;
-- 最大/最小值 SELECT MAX(total_amount) AS highest_order, MIN(total_amount) AS lowest_order FROM orders;
-- 计算累计总和 SELECT order_date, total_amount, SUM(total_amount) OVER (ORDERBY order_date) AS running_total FROM orders;
-- 按分组计算累计总和 SELECT order_date, customer_id, total_amount, SUM(total_amount) OVER ( PARTITIONBY customer_id ORDERBY order_date ) AS customer_running_total FROM orders;
-- 排名函数 SELECT product_name, category, price, ROW_NUMBER() OVER (ORDERBY price DESC) AS price_rank, DENSE_RANK() OVER (PARTITIONBY category ORDERBY price DESC) AS category_price_rank FROM products;
-- 使用CONCAT和REPEAT构建层级缩进 WITHRECURSIVE org_tree AS ( -- 锚点成员 SELECT org_id, org_name, parent_id, 0AS level, org_name AS path FROM organizations WHERE parent_id ISNULL
UNIONALL
-- 递归成员 SELECT o.org_id, o.org_name, o.parent_id, ot.level +1, CONCAT(ot.path, ' > ', o.org_name) FROM organizations o JOIN org_tree ot ON o.parent_id = ot.org_id ) SELECT org_id, CONCAT(REPEAT(' ', level), org_name) AS hierarchical_name, path FROM org_tree ORDERBY path;
2. 将多行数据合并为单行JSON
1 2 3 4 5 6 7 8 9 10 11 12 13 14
-- 将每个客户的订单合并为JSON SELECT c.customer_id, c.customer_name, JSON_ARRAYAGG( JSON_OBJECT( 'order_id', o.order_id, 'order_date', DATE_FORMAT(o.order_date, '%Y-%m-%d'), 'total_amount', o.total_amount ) ) AS orders FROM customers c JOIN orders o ON c.customer_id = o.customer_id GROUPBY c.customer_id, c.customer_name;
3. 枢轴查询(行转列)
1 2 3 4 5 6 7 8 9 10
-- 使用条件聚合实现行转列 SELECT product_id, SUM(IF(quarter ='Q1', sales, 0)) AS Q1_sales, SUM(IF(quarter ='Q2', sales, 0)) AS Q2_sales, SUM(IF(quarter ='Q3', sales, 0)) AS Q3_sales, SUM(IF(quarter ='Q4', sales, 0)) AS Q4_sales, SUM(sales) AS total_sales FROM sales GROUPBY product_id;
4. 计算连续值的差异
1 2 3 4 5 6 7 8 9 10 11 12 13 14
-- 使用窗口函数计算每日销售额同比增长 SELECT current_date, current_sales, previous_sales, ROUND((current_sales - previous_sales) / previous_sales *100, 2) AS growth_percent FROM ( SELECT sale_date AScurrent_date, total_sales AS current_sales, LAG(total_sales) OVER (ORDERBY sale_date) AS previous_sales FROM daily_sales ) t WHERE previous_sales ISNOTNULL;
七、注意事项与性能建议
字符串连接性能考虑:
CONCAT通常比使用字符串运算符(+)更高效
对于大量数据,GROUP_CONCAT可能需要增加其最大长度限制
日期函数使用:
优先使用MySQL内置函数而非自定义实现
日期计算应注意夏令时和闰年等特殊情况的处理
索引考虑:
在函数中包装索引列通常会阻止使用索引(如WHERE MONTH(date_column) = 1)
应该重写为不对索引列应用函数的形式(如WHERE date_column BETWEEN '2024-01-01' AND '2024-01-31')