sql层面语法的总结(mysql层面语法,主要侧重于sql的查询相关的信息量积累)
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)
SELECTcolumn_nameASalias_nameFROMtable;-- AS 可省略SELECTcolumn_name alias_nameFROMtable;2. 常量查询
SELECT'固定文本'ASinfo,100ASnum,NOW()AScurrent_time;3. 表达式计算
SELECTprice,quantity,price*quantityAStotalFROMorders;4. 字符串拼接
SELECTCONCAT(first_name,' ',last_name)ASfull_nameFROMusers;5. 条件分支(CASE WHEN)
SELECTname,score,CASEWHENscore>=90THEN'优秀'WHENscore>=60THEN'及格'ELSE'不及格'ENDASlevelFROMstudents;二、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个)_→ 单个字符
WHEREnameLIKE'张%'-- 张开头WHEREnameLIKE'%三'-- 三结尾WHEREnameLIKE'王_'-- 王+一个汉字转义特殊字符
WHEREpathLIKE'%\_%'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特有 |
SELECTcategory,COUNT(*)AScnt,GROUP_CONCAT(DISTINCTproduct_nameORDERBYpriceDESCSEPARATOR';')ASproductsFROMgoodsGROUPBYcategory;HAVING —— 对分组后的结果筛选
SELECTcategory,AVG(price)ASavg_priceFROMgoodsGROUPBYcategoryHAVINGavg_price>100;-- 不能用 WHEREWHERE 在分组前过滤,HAVING 在分组后过滤。
四、排序与分页
ORDER BY
SELECT*FROMproductsORDERBYpriceDESC,idASC;- 可按列别名排序
- 可按表达式排序:
ORDER BY (price * quantity) DESC
LIMIT 分页
-- 前5条SELECT*FROMtableLIMIT5;-- 从第6条开始取10条(偏移量5,取10条)SELECT*FROMtableLIMIT5,10;-- 推荐写法(MySQL 8.0+)SELECT*FROMtableLIMIT10OFFSET5;大表分页性能问题:
LIMIT 100000, 10会很慢,通常用WHERE id > 上次最大id或子查询优化。
五、执行顺序(非常重要)
你写SQL的顺序 ≠ 数据库执行的顺序:
FROM → 确定表 WHERE → 行级过滤 GROUP BY → 分组 HAVING → 组级过滤 SELECT → 计算表达式、别名 ORDER BY → 排序 LIMIT → 分页案例验证:
SELECTcategory,AVG(price)ASavg_priceFROMgoodsWHEREprice>0GROUPBYcategoryHAVINGavg_price>50ORDERBYavg_priceDESCLIMIT5;因为 HAVING 能识别
avg_price别名,是因为它在 SELECT 之后执行。
六、常用函数补充(查询时会用到)
时间处理
YEAR(date_col),MONTH(date_col),DAY(date_col)DATE_ADD(date,INTERVAL1DAY)DATEDIFF(date1,date2)NOW(),CURDATE(),CURTIME()字符串处理
LENGTH(str),CHAR_LENGTH(str)UPPER(str),LOWER(str)TRIM(str),SUBSTRING(str,start,length)REPLACE(str,from,to)数值处理
ROUND(num,2),FLOOR(num),CEIL(num)ABS(num),RAND()判断与转换
IFNULL(column,默认值)COALESCE(值1,值2,默认值)-- 返回第一个非NULLCAST(columnAS类型)七、一个综合查询示例
把所有机制串起来:
SELECTdepartment,COUNT(*)ASemp_count,ROUND(AVG(salary),2)ASavg_salary,GROUP_CONCAT(DISTINCTnameORDERBYname SEPARATOR', ')ASemployeesFROMemployeeWHEREstatus='active'ANDhire_date>='2020-01-01'GROUPBYdepartmentHAVINGemp_count>=3ORDERBYavg_salaryDESCLIMIT10;小结
你已经把单表查询的主线理解得很清楚了:
SELECT→ 拿什么FROM→ 从哪拿WHERE→ 过滤行GROUP BY + 聚合→ 分组计算HAVING→ 过滤组ORDER BY + LIMIT→ 排序分页
