一、命令的优先级
mysql关键字是有执行优先级区分的,这是重中之重
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from 找到表 where 拿着where指定的约束条件,去表中取出一条条记录 group by 将取出的一条条记录进行分组group by,如果没有group by,则整体作为一组 having 将分组的结果进行having过滤 select 执行select distinct 去重 order by 将结果按条件排序 limit 限制结果的显示条数
二、查
1.简单查询
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1.1查询常量值 select 100; 1.2查询函数 select version(); 1.3避免重复DISTINCT SELECT DISTINCT post FROM employee; 1.4 起别名 1.4.1为字段取别名 select 100%98 AS 结果; 1.4.2为表取别名 select * from girls as A; 1.5 +号的作用 mysql中的+号,只有一个功能:运算符 select 100+90;两个操作数都为数值型,则做加法运算 select '123'+90;其中一方为字符型,试图将字符型数值转换成数值型 如果转换成功,则继续做加法运算 select 'john'+90; 如果转换失败,则将字符型数值转换成0 select null+10; 只要其中一方是null,则结果肯定为null 1.6 concat实现连接 如果要将几个字段的值拼接在一起,想用+号的办法是行不通的。所以可以使用concat select concat(last_name,first_name) as 姓名 from employees; 1.7约束 #1:单条件查询 SELECT name FROM employee WHERE post='sale'; #2:多条件查询 SELECT name,salary FROM employee WHERE post='teacher' AND salary>10000; #3:关键字BETWEEN AND SELECT name,salary FROM employee WHERE salary BETWEEN 10000 AND 20000; SELECT name,salary FROM employee WHERE salary NOT BETWEEN 10000 AND 20000; #4:关键字IS NULL(判断某个字段是否为NULL不能用等号,需要用IS) SELECT name,post_comment FROM employee WHERE post_comment IS NULL; #安全等于<=> =或<>不能用于判断null值,is可以判断null值 select last_name,commission_pct from employees where commission_pct <=>null; 注意:由于<=>可能与别的程序语言混淆,不建议使用<=>,而建议使用上面的is null 1.8 关键字IN集合查询 SELECT name,salary FROM employee WHERE salary=3000 OR salary=3500 OR salary=4000 OR salary=9000 ; SELECT name,salary FROM employee WHERE salary IN (3000,3500,4000,9000) ; SELECT name,salary FROM employee WHERE salary NOT IN (3000,3500,4000,9000) ; 1.9 关键字LIKE模糊查询 通配符’%’ 表示任意个或多个字符,可匹配任意类型和长度的字符 SELECT * FROM employee WHERE name LIKE 'eg%'; 通配符’_’ 表示匹配任意单个字符。 SELECT * FROM employee WHERE name LIKE 'al__'; 1.10 逻辑运算符 算术运算符 +、-、*、/ select 1+2; SELECT name, salary*12 FROM employee; 比较运算符 =,>,<,<=,>=,BETWEEN,NOT BETWEEN,IN,NOT IN,<=>,LIKE,IS NULL,IS NOT NULL <>,!=不等于 逻辑运算符 NOT 或 ! 逻辑非 AND 逻辑与 OR 逻辑或 XOR 逻辑异或 1.11 排序查询 asc是升序,desc是降序 order by 子句中可以支持单个字段、多个字段、表达式、函数、别名 order by 子句一般是放到查询语句的最后面,limit子句除外 可以进行多个字段排序查询 案例:按年薪的高低显示员工的信息和年薪 select *,salary*12*(1+ifnull(commission_pct,0)) nianxin from employees order by nianxin desc; 案例:按姓名的长度显示员工的姓名和工资 select last_name,salary from employees order by length(last_name) desc; 案例:查询员工信息,要求先按工资升序,再按员工编号排序[多个字段排序] select * from employees order by salary ASC,employee_id desc;
查询时把查询的表重命名,就是(select * from table1) as table2这种格式
select ag_dep.*,g.grade_level from ( select avg(salary) ag,department_id from employees group by department_id ) as ag_dep inner join job_grades g on ag_dep.ag between lowest_sal and highest_sal
2.单行函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
2.1字符函数 1.length获取参数的字节个数 select length('john'); 2.concat拼接字符串 select concat(last_name,'_',first_name) 姓名 from employees; 3.变换大小写 select upper('john'); select lower('john'); 4.substr、substring截取字符串 #截取从指定索引处后面所有字符 select substr('李莫愁爱上了陆展元',7) out_put; #截取从指定索引处指定字符长度的字符 select substr('李莫愁爱上了陆展元',1,3) out_put; 5.instr返回子串第一次出现的索引,如果找不到返回0 select instr('杨不悔爱上了小龙女','小龙女') as out_put; 6.trim去除前后空格 select trim(' 张翠翠 '); 7.Lpad用指定的字符实现左填充指定长度(足够长才填充) select Lpad('殷素素',2,'*') as out_put; select Lpad('殷素素',10,'*') as out_put; 8.Rpad用指定的字符实现左填充指定长度(足够长才填充) 9.replace替换 select replace('张无忌爱上了周芷若','周芷若','面筋哥') as out_put; 2.2数字函数 1.round四舍五入 select round(-1.55); select round(2.15); 2.ceil 向上取整,返回>=该参数的最小整数 select ceil(-1.02); 3.floor 向下取整 select floor(10.02); 4.truncate 截断 select truncate(1.6999,1); 5.mod 取余 select mod(10,3); 2.3日期函数 1.now返回当前系统日期+时间 select now(); 2.curdate 返回当前系统日期,不包含时间 select curdate(); 3.curtime 返回当前时间,不包含日期 select curtime(); 4.可以获取指定的部分,年月日小时分钟秒 select year(now()); select year('1998-1-1'); select month('1998-1-1'); 5.str_to_date 将字符通过指定的格式转换成日期 select str_to_date('1999-3-2','%Y-%c-%d') as out_put; 6.date_format 将日期转换成字符 select date_format(now(),'%y年%m月%d日'); #查询有奖金的员工名和入职日期(xx月/xx日/xx年) select last_name,date_format(hiredate,'%m月/%d日/%y年'); 2.4其他函数 select version(); select user(); 2.5流程控制函数 1.if函数 select if(10<5,'大','小'); select last_name,commission_pct,if(commission_pct is null,'没奖金,呵呵','有奖金嘻嘻') as 备注 from employees; 2.case函数 案例:查询员工的工资,要求 部门号=30,显示的工资为1.1倍 部门号=40,显示的工资为1.2倍 部门号=50,显示的工资为1.3倍 其他部门,显示的工资为原工资 case要判断的字段或表达式 when 常量1 then 要显示的值1或语句1; when 常量2 then 要显示的值2或语句2; else 要显示的值n或语句n; end select salary 原始工资,department_id, case department_id when 30 then salary*1.1 when 40 then salary*1.2 when 50 then salary*1.3 else salary end as 新工资 from employees; 3.case函数的使用二:类似多重if 案例:查询员工的工资, 如果工资>20000,显示A级别 如果工资>15000,显示B级别 如果工资>10000,显示C级别 select salary, case when salary>20000 then 'A' when salary>15000 then 'B' when salary>10000 then 'C' else 'D' end as 工资级别 from employees;
3.分组函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
sum和,avg平均值,min最小值,max最大值,count统计个数 select sum(salary) from employees; select avg(salary) from employees; select min(salary) from employees; select max(salary) from employees; select count(salary) from employees; 特点: sum,avg一般用于处理数值型 count(*)&count(1)&count(列名)执行效率比较: (1)如果列为主键,count(列名)效率优于count(1) (2)如果列不为主键,count(1)效率优于count(列名) (3)如果表中存在主键,count(主键列名)效率最优 (4)如果表中只有一列,则count(*)效率最优 (5)如果表有多列,且不存在主键,则count(1)效率优于count(*) 其实如果是统计个数的话用count(1)就可以了。
4.分组查询
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
4.1添加分组前筛选条件,用where 案例:查询邮箱中包含a字符的,每个部门的平均工资 select avg(salary),department_id from employees where email like "%a%" group by department_id; 案例:查询有奖金的每个领导手下员工的最高工资 select max(salary),manager_id from employees where commission_pct is not null group by manager_id; 4.2添加分组后筛选条件用having 复杂筛选条件 #案例1:查询哪个部门的员工数>2 select count(1) num, department_id from employees group by department_id having num > 2; #案例2:查询每个工种有奖金的员工的最高工资 select max(salary), job_id from employees where commission_pct is not null group by job_id; #案例3:查询领导编号>102的每个领导手下的最低工资>5000的领导编号是哪个 select min(salary),manager_id from employees where manager_id>102 group by manager_id having min(salary)>5000; 4.3按函数分组 #案例:按员工姓名的长度分组,查询每一组的员工个数,筛选员工数>5的有哪些 select count(1),length(last_name) from employees group by length(last_name) having count(1)>5 ; 4.5按多个字段分组 #案例:查询每个部门每个工种的员工的平均工资 select avg(salary),department_id,job_id from employees group by department_id, job_id; 4.6分组后添加排序 #案例:查询每个部门每个工种的平均工资,并且按平均工资的高低显示 select avg(salary),department_id,job_id from employees group by job_id order by avg(salary) desc ; 4.7笛卡尔积 案例: select last_name,department_name from employees,departments; 笛卡尔积:表1有m行,表2有n行,结果=m*n行 发生原因:没有添加有效的连接条件 如何避免:添加有效的连接条件
5.连表查询
6.子查询
注意:子查询比连接查询的效率低,尽量不要使用子查询
执行子查询时,MYSQL需要创建临时表,查询完毕后再删除这些临时表,所以,子查询的速度会受到一定的影响,这里多了一个创建和销毁临时表的过程。
7.联合查询
union 联合 合并:将多条查询语句的结果合并成一个结果
语法:
查询语句1
union
查询语句2
union
查询语句3
特点:
1.要求多条查询语句的查询列数是一致的
2.要求多条查询语句的查询每一列的类型和顺序最好一致
3.默认自动去重,如果想不去重,那么union all可以包含重复项
应用场景:
要查询的结果来自于多个表,且多个表没有直接的连接关系,但查询的信息一致时
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
案例:查询部门编号>90或邮箱包含a的员工信息 select * from employees where email like '%a%' union select * from employees where department_id>90; 案例:查询中国用户中男性的信息以及外国用户中男性的用户信息 select id,cname,csex from t_ca where csex="男" union select t_id,tName,tGender from t_ua where tGender='male';
三、增
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1.方式1经典插入方式 insert into 表名 (name,sex,phone) values('alex','male',18); 2.方式2 语法: insert into 表名 set 列名=值,列名=值,... 两种方式pk 1.方式1支持插入多行,方式2不支持 2.方式1支持子查询,方式2不支持
四、删
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
方式一:delete 语法: delete from 表名 where 筛选条件; 方式二:truncate全表删除 语法:truncate table 表名; 两种删除方式对比: 1.delete可以加where条件,truncate不能加 2.truncate删除,效率要高一些 3.加入要删除的表有自增列,如果用truncate,再插入会从1开始 4.truncate删除没有返回值,delete删除有返回值 5.truncate删除不能回滚,delete删除可以回滚
五、改
1.修改单表的记录
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
语法: update 表名 set 列=新值,列=新值 where 筛选条件
2.修改多表的记录
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
语法: update 表1 别名 inner|left|right join 表2 别名 on 连接条件 set 列=值,... where 筛选条件; 案例1:修改张无忌的女朋友的手机号为114 update boys bo inner join beauty b on bo.id=b.boyfriend_id set b.phone="114" where bo.boyName="张无忌"; 案例2:修改没有男朋友的女神的男朋友编号都为2号 update boys right join beauty b on bo.id=b.boyfriend_id set b.boyfriend_id=2 where b.id is null;