creat 新增
INSERT 新增语句
INSERT [INTO] table_name [(column [, column] ...)] VALUES (value_list) [, (value_list)] ... -- value_list: value [, value] ...INTO 可以省略,写上可读性更好
- 表
create table users ( id bigint, name varchar(20) comment '用户名' );三种插入方式
单行全列插入
insert into users values (1, '张三'); insert into users values (2, '李四');不写列名,值的数量、顺序必须和表定义的列完全一致
- 单行指定列插入
insert into users(id, name) values (3, '王五');括号里写明要插入哪些列,值和指定的列一一对应、顺序匹配
- 多行指定列插入
insert into users(id, name) values (4, '赵六'), (5, '钱七');一条 SQL 写多组 (值),逗号隔开,一次性插入多条
查询验证:
select * from users;
总结
- 全列插入:省略列列表,值要和表所有列对齐
- 指定列插入:只给部分字段赋值,值和写出来的列对齐
- 多行插入:一条 INSERT 多个 (value_list),减少数据库交互,
性能优于多次单行insert- 字符串类型的值,要用单引号包裹;数字不需要引号
-- 创建users表 create table users ( id bigint, name varchar(20) comment '姓名' ); -- 单行全列插入 insert into users values (1, '张三'); insert into users values (2, '李四'); select * from users; -- 单行指定列插入 , 写id name, 值跟指定列匹配 insert into users(id, name) values (3, '王五'); -- 多行指定列插入 insert into users(id, name) values (4, '赵六'), (5, '钱七');
Retrieve检索
SELECT 检索语句
语法
SELECT [DISTINCT] select_expr [, select_expr ...] [FROM table_references] [WHERE where_condition] [GROUP BY {col_name | expr}, ...] [HAVING where_condition] [ORDER BY {col_name | expr} [ASC | DESC], ... ] [LIMIT {[offset,] row_count | row_count OFFSET offset}]- 执行顺序:
FROM→WHERE→GROUP BY→HAVING→SELECT(DISTINCT)→ORDER BY→LIMIT- 常用 Select 查询示例
-- 创建学生成绩表 CREATE TABLE exam ( id BIGINT, name VARCHAR(20) COMMENT '同学姓名', chinese FLOAT COMMENT '语文成绩', math FLOAT COMMENT '数学成绩', english FLOAT COMMENT '英语成绩' ); -- 插入测试数据 INSERT INTO exam (id, name, chinese, math, english) VALUES (1, '唐三藏', 67, 98, 56), (2, '孙悟空', 87, 78, 77), (3, '猪悟能', 88, 98, 90), (4, '曹孟德', 82, 84, 67), (5, '刘玄德', 55, 85, 45), (6, '孙权', 70, 73, 78), (7, '宋公明', 75, 65, 30);
(1)查询全部列SELECT * FROM exam;
(2)查询指定列(姓名、语文、数学)
SELECT name, chinese, math FROM exam;
(3)DISTINCT 去重(示例:查询不重复的数学分数)SELECT DISTINCT math FROM exam;
(4)WHERE 条件过滤-- 查询语文大于80分的学生 SELECT * FROM exam WHERE chinese > 80;
(5)计算总分、别名ASSELECT name, chinese + math + english AS total_score FROM exam;
(6)ORDER BY 排序-- 按总分降序排序 SELECT name, chinese + math + english AS total_score FROM exam ORDER BY total_score DESC;
(7)LIMIT 分页-- 从第0条开始,取3条(前3条数据) SELECT * FROM exam LIMIT 0,3;
(8)GROUP BY + HAVING 分组过滤-- 按数学成绩分组,只展示分组后平均分大于85的组 SELECT math, AVG(chinese) avg_chinese FROM exam GROUP BY math HAVING avg_chinese > 85;
- WHERE 和 HAVING 核心区别
(1)WHERE:分组之前筛原始行,不能写AVG、SUM、COUNT这类聚合函数
(2)HAVING:分组统计完之后筛分组结果,可以使用聚合函数
select
全列查询
select * from exam;- 指定列查询
(1)查询编号、姓名、语文成绩select id, name, chinese from exam;- 查询字段为表达式
(1)常量表达式select id, name, 10 from exam;
(2)常量运算select id, name, 10 + 1 from exam;
(3)语文成绩全部 +10 分select id, name, chinese + 10 from exam;
(4)计算三科总分select id, name, chinese + math + english from exam;- 给查询列起别名 AS
select id, name, chinese + math + english as 总分 from exam;如果别名有空格,要用引号包裹:as '总 分'
- DISTINCT 去重
(1)不去重,直接查数学(会出现两个 9 )select math from exam;
(2)去重,重复的分数只保留一条select distinct math from exam;
(3)重点:distinct 是对select 后面所有字段组合整体去重,不是只对紧跟它的那一列
比如select distinct math,name from exam,只有 math 和 name 全都一样,才算重复总结
(1)*代表所有列;推荐开发时尽量不写*,明确写出需要的字段
(2)select 后面不光可以写字段名,还可以写计算式(加减)、固定常量
(3)as别名:给计算出来的新列起一个好看的表头名字
(4)distinct:去掉结果里完全重复的行
WHERE 条件查询
语法
SELECT select_expr [, select_expr] ... [FROM table_references] WHERE where_condition;WHERE:用来过滤行,只取出满足where_condition条件的数据- 注意:WHERE写在FROM之后,GROUP BY之前
比较运算符
- 重点易错:
(1)判断空值:IS NULL,不要写= NULL
(2)BETWEEN是左右都包含,闭区间
(3)LIKE通配符:%多个,_一个逻辑运算符
优先级:NOT > AND > OR,不确定优先级建议加括号()常见坑总结
where col = null永远查不到数据;where col IS NULLNULL <=> NULL返回 1,只有<=>支持 NULL 相等比较LIKE如果不带通配符,效果等价于=IN里面如果有 NULL,NOT IN容易出现查询异常BETWEEN ... AND ...顺序不能反,小值在前、大值在后WHERE 查询示例
基本比较查询
查询英语不及格(<60)的同学及英语成绩
select name, english from exam where english < 60;
- 查询语文成绩高于英语成绩的同学
select name, chinese, english from exam where chinese > english;
- 总分在 200 分以下的同学
select name, chinese + math + english as 总分 from exam where chinese + math + english < 200;
- 重点坑:WHERE 里不能用别名
-- 错误写法,where不能识别select里定义的别名【总分】 select name, chinese + math + english as 总分 from exam where 总分 < 200;AND 和 OR(逻辑运算符)
优先级:AND > OR,不确定优先级一定要加 ()
- 语文 > 80并且英语 > 80
select * from exam where chinese > 80 and english > 80;
- 语文 > 80 或者 英语 > 80
select * from exam where chinese > 80 OR english > 80;
- 优先级对比
-- 等价于:chinese>80 OR (math>70 AND english>70) select * from exam where chinese > 80 or math > 70 and english > 70; -- 加括号改变顺序:(chinese>80 OR math>70) AND english>70 select * from exam where (chinese > 80 or math > 70) and english > 70;
范围查询 BETWEEN / IN
语文分数 [80,90](闭区间,包含两端)
-- BETWEEN AND select name, chinese from exam where chinese between 80 and 90; -- AND 比较符 select name, chinese from exam where chinese >= 80 and chinese <= 90;
BETWEEN 前面小值,后面大值,写反查不到数学是 78、79、98、99
-- IN写法(简洁推荐) select name, math from exam where math in (78, 79, 98, 99); -- OR写法 select name, math from exam where math = 78 or math = 79 or math = 98 or math = 99;
模糊查询 LIKE
通配符:
(1)%:任意多个字符(0 个、1 个、多个都行)
(2)_:单个任意字符- 查询所有姓孙的同学
- 查询姓孙,名字一共两个字(孙 X)
NULL 空值查询
(1)不能用= NULL/!= NULL,永远查不到
(2)判断空:IS NULL;非空:IS NOT NULL- 插入一条英语为 NULL 的数据
insert into exam values (8, '张飞', 27, 0, NULL);- 查询英语成绩是 NULL
- 查询英语成绩不是 NULL
- 重要特性:NULL 和任何数字运算,结果都是 NULL
select name, chinese + math + english as 总分 from exam;(1)张飞那一行总分会是 NULL,因为 english 是 NULL
总结
- WHERE 在 FROM 之后;WHERE不能使用 select 中定义的别名
- AND 优先级高于 OR,复杂条件建议括号
- NULL 判断只用
IS NULL / IS NOT NULL,禁止=NULLBETWEEN a AND b:a <= value <= b,左右都包含- LIKE:
%匹配任意长度;_只匹配 1 个字符- NULL 参与算术运算,结果直接为 NULL
ORDER BY 排序
语法
SELECT ... FROM table_name [WHERE ...] ORDER BY {列名 | 表达式} [ASC | DESC], ... ;- ASC:升序,从小到大,默认就是 ASC,可以省略不写
- DESC:降序,从大到小
- 可以写多个排序字段:先按第一个字段排序;
第一个字段值相同,再按第二个字段排序,以此类推示例
单字段升序(数学成绩从低到高)
select name, math from exam order by math asc;select name, math from exam order by math;二者等价
- 单字段降序(语文成绩从高到低)
select name, chinese from exam order by chinese desc;
- NULL 排序规则
select name, english from exam order by english desc;NULL 在排序时,视作比任何值都小
- 多字段排序
select name, math, english, chinese from exam order by math desc, english asc, chinese asc;需求:数学降序,数学相同则英语升序,英语相同则语文升序
执行优先级:先排 math → math 相等才比较 english → english 相等再比较 chinese- 表达式排序(总分排序)
select name, chinese + math + english from exam order by chinese + math + english desc;注意:只要任意一科是 NULL,相加结果就是 NULL
- 使用别名排序
select name, chinese + math + english as 总分 from exam order by 总分 desc;
- WHERE + ORDER BY 组合
select * from exam where english is not null order by chinese desc;先过滤,再排序:查询英语不为 NULL 的同学,语文降序
顺序:WHERE 写在 ORDER BY 前面- 注意事项
(1)如果没有写ORDER BY,数据库返回行的顺序是不确定、未定义的,
绝对不能依赖这个默认顺序;
(2)ORDER BY支持:列名、计算表达式、列别名;
(3)NULL 排序:比所有正常值都小,ASC时在最上方,DESC时在最下方;
(4)多字段排序,每个字段可以单独指定ASC/DESC,不是写一个 desc 后面全部生效。
分页查询 LIMIT
核心
MySQL 分页是用
LIMIT,起始下标从 0 开始公式:start = (页码 - 1) * 每页条数
三种语法
LIMIT num:从下标 0 开始,取 num 条
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT num;LIMIT start, num:从下标start开始,取num条(逗号写法)SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT start, num;LIMIT num OFFSET start:从下标start开始,取num条(推荐,可读性更好)SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT num OFFSET start;注意:
LIMIT 3 OFFSET 6等价于LIMIT 6,3例子
第 1 页:limit 0,3 → start=(1-1)*3=0
select * from exam order by id asc limit 0, 3;取出 id:1、2、3
- 第 2 页:
limit 3,3→ start=(2-1)*3=3select * from exam order by id asc limit 3, 3;取出 id:4、5、6
- 第 3 页:
limit 6,3→ start=(3-1)*3=6select * from exam order by id asc limit 6, 3;取出 id:7、8,不足 3 条,有多少返回多少,不会报错
分页通用公式
已知:页码 page,每页条数 pageSize
LIMIT (page-1)*pageSize , pageSize
例子:每页 5 条,第 4 页 → limit 15,5
偏移量 start = (当前页码 - 1) * 每页条数
LIMIT start, pageSize比如:第 4 页,每页 3 条 → start=(4-1)*3=9 →
limit 9,3注意事项
- 分页一般搭配
ORDER BY,否则每次分页数据顺序不稳定LIMIT是 MySQL 方言,Oracle、SQL Server 分页语法不一样- 数据量大的时候,
offset很大时查询会变慢(深分页问题)