my sql 常用函数及语句的执行顺序
MySQL 常用函数
1. 字符串函数
-- 连接
SELECT CONCAT('Hello', ' ', 'World'); -- Hello World
SELECT CONCAT_WS(',', 'John', 'Doe'); -- John,Doe-- 截取和长度
SELECT SUBSTRING('MySQL', 3, 3); -- SQL
SELECT LEFT('MySQL', 2); -- My
SELECT RIGHT('MySQL', 3); -- SQL
SELECT LENGTH('MySQL'); -- 5
SELECT CHAR_LENGTH('MySQL'); -- 5-- 大小写转换
SELECT UPPER('mysql'); -- MYSQL
SELECT LOWER('MYSQL'); -- mysql-- 去除空格
SELECT TRIM(' MySQL '); -- MySQL
SELECT LTRIM(' MySQL'); -- MySQL
SELECT RTRIM('MySQL '); -- MySQL-- 替换和查找
SELECT REPLACE('Hello World', 'World', 'MySQL'); -- Hello MySQL
SELECT REPLACE('abc abc', 'abc', 'x'); -- x x
SELECT INSTR('MySQL', 'SQL'); -- 3
SELECT LOCATE('SQL', 'MySQL SQL'); -- 3
SELECT POSITION('SQL' IN 'MySQL'); -- 3
2. 数值函数
-- 基本数学函数
SELECT ABS(-10); -- 10
SELECT ROUND(3.14159, 2); -- 3.14
SELECT CEIL(3.14); -- 4
SELECT FLOOR(3.14); -- 3
SELECT TRUNCATE(3.14159, 2); -- 3.14-- 随机数和符号
SELECT RAND(); -- 0-1之间的随机数
SELECT SIGN(-10); -- -1
SELECT SIGN(10); -- 1
SELECT SIGN(0); -- 0-- 幂和平方根
SELECT POWER(2, 3); -- 8
SELECT SQRT(16); -- 4
SELECT EXP(1); -- 2.718
SELECT LN(10); -- 2.302
SELECT LOG(10, 100); -- 2
3. 日期时间函数
-- 当前时间
SELECT NOW(); -- 2024-01-15 10:30:25
SELECT CURDATE(); -- 2024-01-15
SELECT CURTIME(); -- 10:30:25
SELECT UNIX_TIMESTAMP(); -- 时间戳-- 日期提取
SELECT YEAR('2024-01-15'); -- 2024
SELECT MONTH('2024-01-15'); -- 1
SELECT DAY('2024-01-15'); -- 15
SELECT HOUR('10:30:25'); -- 10
SELECT MINUTE('10:30:25'); -- 30-- 日期计算
SELECT DATE_ADD('2024-01-15', INTERVAL 7 DAY); -- 2024-01-22
SELECT DATE_SUB('2024-01-15', INTERVAL 1 MONTH); -- 2023-12-15
SELECT DATEDIFF('2024-01-20', '2024-01-15'); -- 5
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s'); -- 2024-01-15 10:30:25
4. 条件函数
-- CASE WHEN
SELECT name,salary,CASE WHEN salary > 10000 THEN '高薪'WHEN salary > 5000 THEN '中薪'ELSE '低薪'END as salary_level
FROM employees;-- IF函数
SELECT IF(score >= 60, '及格', '不及格') as result FROM students;
SELECT IFNULL(NULL, '默认值'); -- 默认值
SELECT COALESCE(NULL, NULL, '第一个非空值'); -- 第一个非空值-- 空值处理
SELECT NULLIF(10, 10); -- NULL
SELECT NULLIF(10, 20); -- 10
5. 窗口函数(MySQL 8.0+)
-- 排名函数
SELECT name,salary,ROW_NUMBER() OVER (ORDER BY salary DESC) as rn,RANK() OVER (ORDER BY salary DESC) as rk,DENSE_RANK() OVER (ORDER BY salary DESC) as dr
FROM employees;-- 聚合窗口函数
SELECT department,name,salary,AVG(salary) OVER (PARTITION BY department) as avg_dept_salary,SUM(salary) OVER (PARTITION BY department) as total_dept_salary
FROM employees;
SQL 语句执行顺序
逻辑执行顺序:
-- 书写顺序
SELECT DISTINCT column, aggregate_function
FROM table1
JOIN table2 ON join_condition
WHERE where_condition
GROUP BY group_columns
HAVING having_condition
ORDER BY order_columns
LIMIT limit_count;-- 实际执行顺序
1. FROM 和 JOIN
2. WHERE
3. GROUP BY
4. HAVING
5. SELECT
6. DISTINCT
7. ORDER BY
8. LIMIT
详细执行步骤:
1. FROM 和 JOIN - 确定数据源
FROM employees e
JOIN departments d ON e.dept_id = d.id
- 执行表连接
- 生成虚拟表 VT1
2. WHERE - 行级过滤
WHERE e.salary > 5000 AND d.name = 'IT'
- 过滤不符合条件的行
- 生成虚拟表 VT2
3. GROUP BY - 分组
GROUP BY e.department, YEAR(e.hire_date)
- 按指定列分组
- 生成虚拟表 VT3
4. HAVING - 组级过滤
HAVING AVG(e.salary) > 8000
- 过滤不符合条件的分组
- 生成虚拟表 VT4
5. SELECT - 选择列
SELECT e.department, YEAR(e.hire_date) as hire_year,COUNT(*) as emp_count,AVG(e.salary) as avg_salary
- 计算表达式
- 生成虚拟表 VT5
6. DISTINCT - 去重
SELECT DISTINCT department, hire_year
- 去除重复行
- 生成虚拟表 VT6
7. ORDER BY - 排序
ORDER BY hire_year DESC, avg_salary ASC
- 排序结果集
- 生成虚拟表 VT7
8. LIMIT - 限制行数
LIMIT 10
- 返回指定数量的行
完整示例:
-- 查询:找出IT部门平均薪资最高的前3个入职年份
SELECT YEAR(hire_date) as hire_year,AVG(salary) as avg_salary,COUNT(*) as employee_count
FROM employees e
JOIN departments d ON e.dept_id = d.id
WHERE d.name = 'IT' AND e.salary IS NOT NULL
GROUP BY YEAR(hire_date)
HAVING AVG(salary) > 5000AND COUNT(*) >= 5
ORDER BY avg_salary DESC
LIMIT 3;-- 执行顺序解析:
-- 1. FROM + JOIN: 连接employees和departments表
-- 2. WHERE: 过滤IT部门且薪资不为空的员工
-- 3. GROUP BY: 按入职年份分组
-- 4. HAVING: 过滤平均薪资>5000且员工数>=5的组
-- 5. SELECT: 选择年份、平均薪资、员工数量
-- 6. ORDER BY: 按平均薪资降序排序
-- 7. LIMIT: 返回前3条记录
重要注意事项:
- WHERE 中不能使用 SELECT 别名(因为 WHERE 先于 SELECT 执行)
- HAVING 中可以使用聚合函数(因为 HAVING 在 GROUP BY 之后执行)
- ORDER BY 中可以使用 SELECT 别名(因为 ORDER BY 在 SELECT 之后执行)
- 窗口函数在 SELECT 阶段执行,但可以在 ORDER BY 中使用
理解这个执行顺序对于编写高效、正确的 SQL 查询非常重要!