sql层面语法的总结(mysql层面语法,主要侧重于sql的查询相关的信息量积累)
这个文章主要是针对sql语法的逻辑内容
单表查询相关机制设计的讲解
在使用sql之前,我们要了解一个基础概念,也就是关系型数据库。
其实用大白话讲,就是一个table表格,一个excel表格。
列头和数据
我们主要研究的就是这个从这个表格里去到我们想要的数据
于是就有了
select 列
from table
where 列="对应的数据"
and 列="对应的数据"
这样就取到了想要的数据。
但是为了处理更加复杂的
我们的目标,就是找到这个table里面的所有的数据,我们看看sql查询,提供了哪些机制供使用
type类型
文本,时间,数据
对于查询的列可以限制使用:
distinct这个关键字处理去重
查询where的关键字
对应的单个列数据
1.对应的列匹配数据,列名 = 某个值
对于时间和数字,还可以大于,小于,等于这些
空值判断 列 IS NULL / IS NOT NULL 不能用 = NULL
4.like机制,模糊查询
对应多个数据
1.in机制,锁定固定的数据,就是列名对应的多个数据
2.between机制,在某某区间
备注:多个查询对象可以用and和or连接
计算查询
第一个阶段
对某个列进行操作,常见的操作
count()个数
avg()平均值
max() 最大值
min() 最小值
第二个阶段
对列的类型去进一步操作:
groupby 这个就贵吧数据分成一坨坨在计算
第三个阶段
对计算出来的值做限制
只显示对应计算出来的值
你总结的这部分已经抓住了单表查询的核心骨架,很清晰。在此基础上,我帮你补充一些MySQL中常用但容易忽略的SQL语法细节 ,侧重于查询相关的信息量积累,让你的"工具箱"更完整。
一、SELECT 子句的更多机制
1. 列别名(AS)
sql
SELECT column_name AS alias_name FROM table;
-- AS 可省略
SELECT column_name alias_name FROM table;
2. 常量查询
sql
SELECT '固定文本' AS info, 100 AS num, NOW() AS current_time;
3. 表达式计算
sql
SELECT price, quantity, price * quantity AS total FROM orders;
4. 字符串拼接
sql
SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM users;
5. 条件分支(CASE WHEN)
sql
SELECT
name,
score,
CASE
WHEN score >= 90 THEN '优秀'
WHEN score >= 60 THEN '及格'
ELSE '不及格'
END AS level
FROM students;
二、WHERE 的补充条件
| 操作符 | 说明 | 示例 |
|---|---|---|
!= 或 <> |
不等于 | WHERE age <> 18 |
<=> |
安全等于(可比较 NULL) | WHERE a <=> NULL |
NOT IN |
不在列表中 | WHERE id NOT IN (1,2,3) |
NOT BETWEEN |
不在区间 | WHERE price NOT BETWEEN 10 AND 100 |
NOT LIKE |
不匹配模式 | WHERE name NOT LIKE 'test%' |
LIKE 的通配符
%→ 任意个字符(含0个)_→ 单个字符
sql
WHERE name LIKE '张%' -- 张开头
WHERE name LIKE '%三' -- 三结尾
WHERE name LIKE '王_' -- 王+一个汉字
转义特殊字符
sql
WHERE path LIKE '%\_%' ESCAPE '\' -- 查找包含下划线的
三、GROUP BY 与聚合函数的细节
常用的聚合函数
| 函数 | 说明 | 注意 |
|---|---|---|
COUNT(*) |
总行数 | 包含 NULL |
COUNT(column) |
非 NULL 行数 | 不含 NULL |
COUNT(DISTINCT column) |
去重后计数 | 常用 |
SUM(column) |
求和 | 忽略 NULL |
AVG(column) |
平均值 | 忽略 NULL |
MAX(column) / MIN(column) |
最大/最小值 | 忽略 NULL |
GROUP_CONCAT(column) |
拼接分组内容 | MySQL特有 |
sql
SELECT
category,
COUNT(*) AS cnt,
GROUP_CONCAT(DISTINCT product_name ORDER BY price DESC SEPARATOR ';') AS products
FROM goods
GROUP BY category;
HAVING ------ 对分组后的结果筛选
sql
SELECT category, AVG(price) AS avg_price
FROM goods
GROUP BY category
HAVING avg_price > 100; -- 不能用 WHERE
WHERE 在分组前过滤,HAVING 在分组后过滤。
四、排序与分页
ORDER BY
sql
SELECT * FROM products
ORDER BY price DESC, id ASC;
- 可按列别名排序
- 可按表达式排序:
ORDER BY (price * quantity) DESC
LIMIT 分页
sql
-- 前5条
SELECT * FROM table LIMIT 5;
-- 从第6条开始取10条(偏移量5,取10条)
SELECT * FROM table LIMIT 5, 10;
-- 推荐写法(MySQL 8.0+)
SELECT * FROM table LIMIT 10 OFFSET 5;
大表分页性能问题:
LIMIT 100000, 10会很慢,通常用WHERE id > 上次最大id或子查询优化。
五、执行顺序(非常重要)
你写SQL的顺序 ≠ 数据库执行的顺序:
FROM → 确定表
WHERE → 行级过滤
GROUP BY → 分组
HAVING → 组级过滤
SELECT → 计算表达式、别名
ORDER BY → 排序
LIMIT → 分页
案例验证:
sql
SELECT category, AVG(price) AS avg_price
FROM goods
WHERE price > 0
GROUP BY category
HAVING avg_price > 50
ORDER BY avg_price DESC
LIMIT 5;
因为 HAVING 能识别
avg_price别名,是因为它在 SELECT 之后执行。
六、常用函数补充(查询时会用到)
时间处理
sql
YEAR(date_col), MONTH(date_col), DAY(date_col)
DATE_ADD(date, INTERVAL 1 DAY)
DATEDIFF(date1, date2)
NOW(), CURDATE(), CURTIME()
字符串处理
sql
LENGTH(str), CHAR_LENGTH(str)
UPPER(str), LOWER(str)
TRIM(str), SUBSTRING(str, start, length)
REPLACE(str, from, to)
数值处理
sql
ROUND(num, 2), FLOOR(num), CEIL(num)
ABS(num), RAND()
判断与转换
sql
IFNULL(column, 默认值)
COALESCE(值1, 值2, 默认值) -- 返回第一个非NULL
CAST(column AS 类型)
七、一个综合查询示例
把所有机制串起来:
sql
SELECT
department,
COUNT(*) AS emp_count,
ROUND(AVG(salary), 2) AS avg_salary,
GROUP_CONCAT(DISTINCT name ORDER BY name SEPARATOR ', ') AS employees
FROM employee
WHERE status = 'active'
AND hire_date >= '2020-01-01'
GROUP BY department
HAVING emp_count >= 3
ORDER BY avg_salary DESC
LIMIT 10;
小结
你已经把 单表查询的主线 理解得很清楚了:
SELECT→ 拿什么FROM→ 从哪拿WHERE→ 过滤行GROUP BY + 聚合→ 分组计算HAVING→ 过滤组ORDER BY + LIMIT→ 排序分页