create table name(id int, name varchar(20)); 创建一个表
insert into name (属性名) values (值)
desc 表明; 查看某表的结构
6 DQL语言
# 进阶1:基础查询# select 查询表 from 表名;# 查询列表可以是:表中的字段、常量值、表达式、函数# 查询的结果是虚拟的表格# 打开库# 1.查询单个字段SELECT last_name From employees;# 2.查询多个字段SELECT last_name,salary,email FROM employees;# 3.查询所有字段,表中的顺序一模一样SELECT*FROM employees;# 4.查询常量值SELECT100;SELECT'john';# 5.查询函数SELECT VERSION();# 6.查询表达式SELECT100%98# 7.1 起别名SELECT100%98AS 结果;SELECT last_name as 姓, first_name as 名 FROM employees;# 7.2 起别名SELECT last_name 姓,first_name 名 FROM employees;# 7.3 别命有特殊符号SELECT last_name AS'out put'FROM employees;# 8. 去重SELECTDISTINCT department_id FROM employees;# 9. +号作用:仅仅只能充当运算符# 查询员工名和姓,连接成一个字段,并显示为 姓名SELECT CONCAT(last_name,' ',first_name)AS 姓名 FROM employees;# 10.显示表结构DESC departments;# 11.自定义null的输出SELECT IFNULL(commission_pct,0)AS 奖金率,
commission_pct
From
employees;
# 进阶2:条件查询/*
语法:
SELECT
查询列表
FROM
表名
WHERE
筛选条件;
分类:
一、按条件表达式筛选
条件运算符:> < = != <> <= >=
二、逻辑运算符
&& || !
and or not
三、模糊查询
like
between
in
is null
*/# 一、按条件表达式筛选#案例1:查询员工工资大于12000的人SELECT concat(last_name,'-',first_name)AS 姓名 from employees where salary >=12000;SELECT*from employees where salary >=12000;#案例2:查询部门编号不等于90号的员工名和部门编号SELECT
CONCAT(last_name,' ',first_name,' id:',department_id)as INFO
FROM
employees
WHERE
department_id <>90;# 二、按逻辑表达式# 案例1:工资在10000到20000之间的员工名、工资及奖金SELECT
CONCAT(last_name,' ',first_name)AS 姓名,
salary AS 工资,
commission_pct AS 奖金,
FROM
employees
WHERE
salary>10000and salary<20000;# 案例2:查询部门编号不是在90-110,或者工资高于15000的员工信息SELECT*FROM employees
WHERE((0<department_id<90)OR(110<department_id))OR salary>15000;
SELECT job_id FROM employees WHERE salary>10000;# 三、模糊查询/*
like
like搭配通配符使用;
通配符:
1.% 任意多个字符,包含0个或多个字符
2._ 任意单个字符
between
in
in null | is not null
*/# 案例1:查询员工名中包含字符a的员工信息SELECT*From employees WHERE last_name LIKE'%a%';# %当作通配符#案例2:查询员工名中第三个字符为a,第五个字符为a的员工名SELECT last_name from employees where last_name LIKE'__a_l%';#案例3:查询员工名中第二个字符为下划线的员工名SELECT last_name FROM employees WHERE last_name LIKE'_$_%'ESCAPE'$';#ESCAPE 表转义#2.between and#案例1:查询员工编号在100-120之间的员工信息SELECT*FROM employees WHERE employee_id BETWEEN100AND120;#闭区间#3.in#案例1:查询员工的工种编号是:AD_VP,IT_PROG,AD_PRESSELECT
last_name,job_id
FROM
employees
WHERE
job_id IN('AD_Vp','IT_PROT','AD_PRES');# 4.isnull#案例1:没有奖金的员工名和奖金率SELECT
last_name,commission_pct
FROM
employees
WHERE
commission_pct ISNULL;#安全等于 <=>:判断是否等于SELECT
last_name,commission_pct
FROM
employees
WHERE
commission_pct <=>NULL;/* is null PK <=>
is null 只能判断 null值,可读性高
<=> 能判断 null 和 is not null ,可读性低
*/SELECT
last_name,
department_id,
salary*12*IFNULL(1+commission_pct,0)AS 年薪
FROM
employees
WHERE
job_id =176;# 练习:# 一、查询没有奖金,且工资小于18000的salary,last_nameSELECT
salary,
last_name
FROM
employees
WHERE(commission_pct isnull)and(salary<18000);#二、查询employees表的结构,job_id不为“IT”或者 工资为12000的员工信息DESC employees;SELECT*FROM
employees
WHERE(job_id notLIKE'IT%')OR(salary =12000);# 三、查看departments表的结构DESC departments;#四、查询部门departments表中涉及到了哪些位置编号SELECT
department_id
FROM
departments;#五、访问select * from employees和 select * from employees WHERE commission_pct like '%%' and last_name like '%%';看看结果是否一样说明为什么SELECT*FROM employees;SELECT*FROM employees WHERE commission_pct LIKE'%%'AND last_name LIKE'%%';
#进阶3:排序查询/*
引入:
select * from employees;
语法:
select 查询表
from 表
【WHERE 筛选条件】
order by 排序列表 【asc | desc】
*/#案例1:查询员工信息,工资从高到底排序SELECT*FROM employees ORDERBY salary DESC;#案例2:查询部门编号>=90的员工信息,按入职时间的先后进行排序SELECT*FROM employees WHERE department_id >=90orderby hiredate ASC;#案例3:按年薪的高低显示员工的信息和年薪【按表达式查询】SELECT*,salary*12*(IFNULL(commission_pct,0)+1)AS 年薪 FROM employees ORDERBY salary*12*(IFNULL(commission_pct,0)+1)DESC;#案例4:按年薪的高低显示员工的信息和年薪【按别名查询】SELECT*,salary*12*(IFNULL(commission_pct,0)+1)AS 年薪 FROM employees ORDERBY 年薪 DESC;#案例5:按姓名的长度显示员工的姓名和工资SELECT LENGTH(last_name) 字节长度,last_name,salary from employees ORDERBY 字节长度;#案例6:查询员工信息,要求先按工资排序,再按员工编号排序【按多个字段排序】SELECT*FROM employees
ORDERBY salary ASC,job_id DESC;#查询员工的姓名、部门号和年薪,按年薪降序,按姓名升序SELECT last_name,department_id,salary*12*(1+IFNULL(commission_pct,0)) 年薪 FROM employees ORDERBY 年薪 DESC, last_name ASC;#查询工资不在8000到17000的员工的姓名和工资,按工资降序SELECT last_name,salary FROM employees WHERE salary<8000OR salary>17000ORDERBY salary DESC;#查询邮箱中包含e的员工信息,并先按邮箱的字节数据降序,再按部门号升序SELECT*FROM employees WHERE email LIKE'%e%'ORDERBY LENGTH(email)DESC,department_id ASC;
#进阶4:常见函数/*
功能:就是python中的封装函数
调用:select 函数名(实参列表) FROM 表;
分类:
1、单行函数
如 concat、length、ifnull等
2、分组函数
*/# 一、字符函数#1.LENGTH SELECT length('wada');#2.concat 拼接#3.upper,lowerselect concat(upper(last_name),lower(first_name)) 姓名 FROM employees;#4.substrSELECT SUBSTR('李莫愁爱上了陆展元',6) out_put;#索引从1开始SELECT SUBSTR('李莫愁爱上了陆展元',1,3) out_put;#切片截取#案例:姓名中首字母大写,其他字母小写,然后用_拼接,显示出来;SELECT CONCAT(UPPER(SUBSTR(last_name,1,1)),'_',LOWER(SUBSTR(last_name,2)))FROM employees;#5.instr 返回字串第一次出现的索引SELECT INSTR('杨不美爱上了我的我','我的我')as out_put;# 返回子字符串的起始索引#6.trim 取出前后的指定字符SELECT TRIM('d'FROM'd d d d d') out_put;#7.lpad,rpad 左填充,右填充SELECT LPAD('殷素素',10,'*')AS out_put;##8.replace 替换SELECTREPLACE('aassd','a','q')AS out_put;
/* Built-in Functioin:
1.LENGTH()
2.INSTR()
3.SUBSTR()
4.TRIM()
5.LPAD/RPAD()
6.REPLACE()
*/# 二、数学函数# round 四舍五入SELECTROUND(1.653,2);#ceil 向上取整,返回大于等于x的最小整数SELECT CEIL(0.1);#floor 向下取整SELECT FLOOR(0.1);#truncate 截断SELECTTRUNCATE(1.65,1);#MOD取余SELECTMOD(-10,-3);#三、日期函数#NOW() 返回当前系统日期SELECTNOW();#CURDATE() 返回当前日期,不包含时间#CURTIME() 返回当前时间,不包含日期#可获得指定的部分,年、月、日、小时、分钟、秒SELECTYEAR(NOW()) 年;SELECTYEAR(hiredate)FROM employees;SELECTMONTH(hiredate)FROM employees;SELECT MONTHNAME(hiredate)FROM employees;#STR_TO_DATE(str,format) 字符转日期SELECT STR_TO_DATE('09-1-2020','%m-%d-%Y');#查询入职日期为4月3号的日期SELECT*FROM employees WHERE hiredate ='1992-4-3';SELECT*FROM employees WHERE hiredate = STR_TO_DATE('4-3-1992','%c-%d-%Y');#DATE_FORMAT(date,format)SELECT DATE_FORMAT(NOW(),'%Y-%c-%d');#查询有奖金的员工名和入职日期(xx月/xx日/xx年)SELECT last_name 姓名,DATE_FORMAT(hiredate,'%m月/%d日/%y年') 入职日期 FROM employees WHERE commission_pct isNOTNULL;#四、其他函数SELECT VERSION();SELECTDATABASE();SELECTuser();#五、流程控制函数#1.if函数SELECTIF(10>5,'大','小');SELECT last_name,commission_pct,IF(commission_pct isnotNULL,'有奖金','无奖金')FROM employees;#2.CASE函数的使用一: /*case 要判断的字段或表达式
when 常量1 then 要显示的值1或语句1;
when 常量2 then 要显示的值2或语句2;
...
else 要显示的值n或语句n;
end
*//*案例:查询员工的工资
要求:
部门=30,显示工资为1.1倍
部门=40,显示工资为1.2倍
部门=50,显示工资为1.3倍
部门=60,显示工资为1.4倍
其他部门,显示为原工资
*/SELECT salary,department_id,case department_id
When30THEN salary*1.1when40THEN salary*1.2WHEN50THEN salary*1.3ELSE salary
ENDas 新工资
FROM employees;#3.case 函数的使用二:类似于 多重if/*
case
when 条件1 then 要显示的值1或语句1
when 条件2 then 要显示的值2或语句2
...
else 要显示的值n或语句n
end
*/# 案例:查询员工的工资情况/*
如果工资>20000,显示A级别
如果工资>15000,显示B级别
如果工资>10000,显示C级别
否则,显示D级别
*/SELECT salary 工资,caseWHEN salary>20000THEN'A级'WHEN salary>15000THEN'B级'WHEN salary>10000THEN'C级'ELSE'D级'ENDAS 工资级别
FROM employees;
#进阶5:分组查询/*
语法:
select 分组函数,列(要求出现在group by的后面)
from 表
【where 筛选条件】
group by 分组列表
【order by 子句】
注意:
查询列表必须特殊,要求是分组函数和group by后出现的字段
特点:
1、分组查询中的筛选条件分为两类
数据源 位置 关键字
分组前筛选 原始表 group by子句的前面 WHERE
分组后筛选 原始表 group by子句的后面 HAVING
注:分组函数做条件筛选肯定是放在having子句中
能用分组前筛选的,就优先考虑使用分组前筛选
2、group by子句支持单个字段分组
3、也可以添加排序
*/#引入:查询每个部门的平均工资SELECTAVG(salary)FROM employees;#案例1:查询每个工种的最高工资SELECTMAX(salary),job_id FROM employees
GROUPBY job_id;#案例2:查询每个位置上的部门个数SELECTCOUNT(*),department_id FROM departments GROUPBY location_id;#添加筛选条件#案例1:邮箱中包含a字符的,每个部门的平均工资SELECTAVG(salary)FROM employees WHERE email LIKE'%a%'GROUPBY department_id;#案例2:查询有奖金的每个领导手下员工的最高工资SELECT manager_id,MAX(salary) 最高工资 FROM employees WHERE commission_pct isnotnullGROUPBY manager_id;#添加复杂的筛选条件#案例1:查询哪个部门的员工个数>2,添加分组后的筛选SELECTCOUNT(*) 员工个数,department_id FROM employees GROUPBY department_id
HAVING 员工个数>2;#案例2:查询每个工种有奖金的员工的最高工资,最高工资>12000的工资编号和其最高工资SELECTMAX(salary) 最高工资, job_id 工种编号 FROM employees WHERE commission_pct isnotnullGROUPBY job_id
HAVING 最高工资>12000;#案例3:查询领导编号>102的每个领导手下的最低工资>5000的领导编号是哪个,以及其最低工资SELECT manager_id 领导编号,MIN(salary),job_id FROM employees WHERE manager_id>102GROUPBY 领导编号
HAVINGMIN(salary)>5000;
#进阶6:连接查询/*
含义:又称多表查询,当查询字段来自于多个表时,就会用到连接查询
笛卡尔乘积现象:表1 有m行,表2有n行,结果m*n行
发生原因:没有有效的连接条件
如何避免:添加有效的连接条件
分类:
按年代分类
sql92标准
sql99标准【推荐】
按功能分类:
内连接:
等值连接
非等值连接
自连接
外连接:
左外连接
右外连接
全外连接
交叉连接
*/#一、sql92标准/*
1.多表等值连接的结果为多表的交集部分
2.n表等值连接,至少需要n-1个条件
3.一般需要为表起别名
4.多表的顺序没有要求
5.可以搭配前面介绍的所有子句使用,比如排序、分组、筛选
*/#1.等值连接#案例1:查询女神名和对应的男神名SELECT`name`,boyName FROM beauty,boys
WHERE beauty.boyfriend_id = boys.id;#案例2:查询员工名和对应的部门名SELECT last_name 员工名, department_name 部门名 FROM employees,departments
WHERE employees.department_id = departments.department_id;#2.查询员工名、工种号、工种名/*
为表起别名
1.提高简洁度
2.区分多个重名的字段
注意:如果为表起了别名,则查询字段就不能使用原来的表名去限定
*/SELECT last_name 员工名,e.job_id 工种号, job_title 工种名
FROM employees e,jobs
WHERE e.job_id = jobs.job_id;#3.筛选#案例1:查询有奖金的员工名、部门名SELECT last_name,department_name
FROM employees E, departments D
WHERE E.department_id = D.department_id AND commission_pct ISNOTNULL;#案例2:查询城市名中第二个字符为o的对应的部门名和城市名SELECT department_name 部门名, city 城市名
FROM departments D,locations L
WHERE D.location_id = L.location_id
AND city LIKE'_o%';#4.分组#案例1:查询每个城市的部门个数SELECT city 城市,count(*) 部门个数
FROM locations L,departments D
WHERE L.location_id=D.location_id
GROUPBY 城市;#案例2:查询有奖金的每个部门的部门名和部门的领导编号和部门的最低工资SELECT department_name 部门名,D.manager_id 领导编号,MIN(salary) 最低工资
FROM employees E, departments D
WHERE E.department_id = D.department_id
and commission_pct isnotnullGROUPBY 部门名,D.manager_id;#5.排序#案例:查询每个工种的工种名和员工的个数,并且按员工个数降序SELECT job_title 工种名,COUNT(*) 员工个数
FROM employees e,jobs j
WHERE e.job_id = j.job_id
GROUPBY 工种名
ORDERBY 员工个数 DESC;#6.三表连接#案例:查询员工名、部门名和所在城市SELECT last_name 员工名, department_name 部门名,city 城市
FROM employees E, departments D, locations L
WHERE E.department_id = D.department_id AND D.location_id =L.location_id;#2、非等值连接# 插入表CREATETABLE job_grades
(grade_level VARCHAR(3),
lowest_sal INT,
highest_sal INT);INSERTinto job_grades
VALUES('A',1000,2999);INSERTinto job_grades
VALUES('B',3000,5999);INSERTinto job_grades
VALUES('C',6000,9999);INSERTinto job_grades
VALUES('D',10000,14999);INSERTinto job_grades
VALUES('E',15000,24999);INSERTinto job_grades
VALUES('A',25000,40000);#案例1:查询员工的工资和工资级别SELECT salary,grade_level
FROM employees E,job_grades J
WHERE salary BETWEEN J.lowest_sal AND J.highest_sal;#3.自连接#案例:查询员工名和其上级的名称SELECT e.last_name 员工名, e.employee_id 员工编号, m.last_name,m.manager_id 上级编号
FROM employees e,employees m
WHERE e.manager_id = m.employee_id;
SQL99
#二、sql99语法/*
语法:
select 查询列表
FROM 表1 别名 【连接类型】
join 表2 别名
on 连接条件
【where 筛选条件】
【GROUP BY 分组】
【having 筛选条件】
【order by 排序列表】
分类:
内连接:inner
外连接
左外:left 【outer】
右外:right【outer】
全外:full【outer】
交叉连接:cross
*/#一、内连接/*
语法
select 查询列表
from 表1 别名
INNER JOIN 表2 别名
on l连接条件
分类:
等值
非等值
自连接
特点:
1.添加排序、分组、筛选
2.inner可以省略
3.筛选条件放在where后面,连接条件放在on后面,提高分离性,便于阅读
4.inner join连接和sql92语法的等值连接效果是一样的,都是查询多表的交集
*/#1、等值连接#案例1:查询员工名、部门名SELECT last_name,department_name
FROM employees e INNERJOIN departments d
ON e.department_id = d.department_id;#案例2:查询名字中包含e的员工名和工种名SELECT last_name 员工名,job_title 工种名
FROM employees e
INNERJOIN jobs j
on j.job_id = e.job_id
WHERE e.last_name LIKE'%e%';#案例3:查询部门个数>=3的城市名和部门个数SELECT city 城市名,count(*) 部门个数
FROM locations l
INNERJOIN departments d
on l.location_id =d.location_id
groupby city
having 部门个数>=3;#案例4:查询部门员工个数>3的部门名和员工个数,并按个数降序(排序)SELECT department_name 部门名,COUNT(*) 员工个数
FROM departments d
INNERJOIN employees e
on d.department_id =e.department_id
GROUPBY department_name
HAVING 员工个数>3ORDERBY 员工个数 DESC;#5.查询员工名、部门名、工种名、并按部门名降序SELECT last_name 员工名,department_name 部门名,job_title 工种名
FROM employees e
INNERJOIN departments d
on e.department_id = d.department_id
INNERJOIN jobs j
on e.job_id = j.job_id
ORDERBY 部门名 DESC;#二)、非等值连接#查询员工的工资级别SELECT salary 工资,grade_level 工资级别
FROM employees e
innerjoin job_grades g
on e.salary BETWEEN g.lowest_sal and g.highest_sal;#查询每个工资级别的个数>20的个数,并且按工资级别降序SELECT COUTN(*) 个数,grade_level 工资级别
FROM employees e
INNERJOIN job_grades g
ON e.salary BETWEEN g.lowest_sal and g.highest_sal
GROUPBY 工资级别
HAVINGCOUNT(*)>20ORDERBY 工资级别 DESC;#三)、自连接#查询员工的名字、上级的名字SELECT e.last_name,m.last_name
FROM employees e
INNERJOIN employees m
ON e.manager_id = m.employee_id;#二、外连接/*
应用场景:用于查询一个表中有,另一个表没有的记录
特点:
1、外连接的查询结果为主表中的所有记录
如果从表中有和它匹配的,则显示匹配的值
如果从表中没有和它匹配的,则显示null
外连接查询结果=内连接结果+主表中有而从表没有的记录
2、左外连接:left join左边的是主表
右外连接:right join右边的是主表
3、左外和右外交换两个表的顺序,可以实现同样的效果
*/#引入:查询没有男朋友的女神名#左外连接SELECT b.name,bo.*FROM beauty b
leftouterjoin boys bo
on b.boyfriend_id = bo.id;#案例1:查询哪个部门没有员工SELECT d.*,e.employee_id
FROM departments d
leftouterjoin employees e
on e.department_id = d.department_id
HAVING e.employee_id isnull;#交叉连接 CROSS JOIN 其实就是笛卡尔乘积#练习1:查询编号>3的女神的男朋友信息SELECT bo.*, b.id
FROM beauty b
LEFTJOIN boys bo
ON bo.id = b.boyfriend_id
WHERE b.id >3;#练习2:查询哪个城市没有部门SELECT city 城市
FROM locations l
leftjoin departments d
on d.location_id = l.location_id
WHERE d.location_id isNULL;#练习3:查询部门名为SAL或IT的员工信息SELECT d.department_name,e.*FROM employees e
RIGHTJOIN departments d
ON e.department_id = d.department_id
WHERE d.department_name ='SAL'or d.department_name ='IT';
子查询
#进阶7:子查询/*
含义:
出现在其他语句中的select语句,称为子查询或内查询
外部的查询语句,称为主查询或外查询
分类:
按子查询出现的位置:
select后面:
仅仅支持标量子查询
from后面:
支持表子查询
where或having后面:
标量子查询(单行)
列子查询(多行)
行子查询
exists后面(相关子查询):
表子查询
按结果集的行列数不同:
标量子查询(结果集只有一行一列)
列子查询(结果集只有一列多行)
行子查询(结果集有一行多列)
表子查询(结果集一般为多行多列)
*/#一、WHERE或HAVING后面/*
1.标量子查询
2.列子查询
3.行子查询
特点:
1.子查询放在小括号内
2.子查询一般放在条件的右侧
3.标量子查询,一般搭配着单行操作符使用
4.子查询的执行优先于主查询执行,主查询的条件用到了子查询的结果
> < >= <= = <>
列子查询:一般搭配着多行操作符使用
in、any/some、all
*/#1.标量子查询#案例1:谁的工资比Abel高?SELECT*FROM employees
WHERE salary>(SELECT salary FROM employees
WHERE last_name ='Abel');#案例2:查询job_id与141号员工相同,salary比143号员工多的员工 姓名、job_id和工资SELECT last_name,job_id,salary FROM employees
WHERE job_id =(SELECT job_id FROM employees
WHERE employee_id =141)AND salary >(SELECT salary FROM
employees
WHERE employee_id=143);#案例3:返回公司工资最少的员工的last_name,job_id和salarySELECT last_name,job_id,salary
FROM employees
WHERE salary =(SELECTMIN(salary)FROM employees
);#案例4:查询最低工资>50号部门最低工资的部门id和其最低工资SELECT department_id,MIN(salary)FROM employees
GROUPBY department_id
HAVINGMIN(salary)>(SELECTMIN(salary)FROM employees
WHERE department_id =50);
#多行子查询/*
操作符:
1.IN/NOT IN 等于列表中的任意一个
2.ANY|SOME 和子查询返回的某一个值比较
3.ALL 和子查询返回的所有值比较
*/#案例1:返回location_id是1400或1700的部门中的所有员工姓名SELECT department_name,location_id
from departments GROUPBY location_id
WHERE location_id =1400SELECT last_name FROM employees
WHERE department_id IN(SELECTDISTINCT department_id
from departments
WHERE location_id IN(1400,1500));#案例2:返回其他部门中比job_id为"IT_PROG"部门任一工资低的员工的工号、姓名、job_id以及salarySELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary <ANY(SELECT salary
FROM employees
WHERE job_id ='IT_PROG')AND job_id <>'IT_PROG';#案例3:返回其它部门中比job_id为'IT_PROG'部门所有工资都低的员工的员工号、姓名、job_id以及salarySELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary <(SELECTMIN(salary)FROM employees
WHERE job_id ='IT_PROG')AND job_id <>'IT_PROG';#3.行子查询#案例:查询员工编号最小并且工资最高的员工信息SELECT*FROM employees
WHERE(employee_id,salary)=(SELECTMIN(employee_id),MAX(salary)FROM employees
);SELECT*FROM employees
WHERE employee_id =(SELECTMIN(employee_id)FROM employees
)AND salary =(SELECTMAX(salary)FROM employees
);#二、select 后面#注:只支持标量子查询#案例1:查询每个部门的员工个数SELECT d.*,(SELECTCOUNT(*)FROM employees e
WHERE e.department_id = d.department_id
) 个数
FROM departments d;#案例2:查询员工号=102的部门名SELECT(SELECT department_name FROM departments d
INNERJOIN employees e
ON e.department_id =d.department_id
WHERE e.employee_id =102);#三、from后面/*
将子查询结果充当一张表,要求必须起别名
*/#案例:查询每个部门的平均工资的工资等级SELECT aga.*,department_id,grade_level
FROM(SELECTAVG(salary) ag,department_id FROM employees
GROUPBY department_id
) aga
INNERJOIN job_grades g
ON aga.ag BETWEEN g.lowest_sal and g.highest_sal;#四、exists后面(相关子查询)/*
语法:
exists(完整的查询语句)
结果:0,1
有值为1
*/#案例1:查询有员工的部门名SELECT department_name
FROM departments d
WHEREEXISTS(SELECT*FROM employees e
WHERE e.department_id =d.department_id
);#案例2:查询没有女朋友的男神信息SELECT bo.*FROM boys bo
WHERENOTEXISTS(SELECT*FROM beauty b
WHERE bo.id = b.boyfriend_id
);#练习#1.查询和Zlotkey相同部门的员工姓名和工资SELECT last_name,salary,department_name FROM employees,departments
WHERE department_name =(SELECT department_name FROM departments d,employees e
WHERE last_name ='Zlotkey'AND d.department_id =e.department_id
);#2.查询工资比公司平均工资高的员工的员工号,姓名和工资SELECT employee_id,last_name,salary FROM employees e
WHERE salary >(SELECTavg(salary)FROM employees
);#3.查询各部门中工资比本部门平均工资高的员工的员工号,姓名和工资SELECT employee_id,last_name,salary FROM(SELECTAVG(salary) aa,department_id FROM employees
GROUPBY department_id
) A
INNERJOIN employees e
ON e.department_id = A.department_id
WHERE salary>A.aa;#4.查询和姓名中包含字母u的员工在相同部门工作的员工的工号和姓名SELECT employee_id,last_name FROM employees
WHERE department_id IN(SELECTDISTINCT department_id FROM employees
WHERE last_name LIKE'%u%');SELECT employee_id,last_name FROM(SELECTDISTINCT department_id FROM employees
WHERE last_name LIKE'%u%') d INNERJOIN employees e
on d.department_id = e.department_id
WHERE e.department_id;#5.查询管理者为King的员工姓名和工资SELECT last_name,salary FROM employees e
WHERE e.manager_id IN(SELECT employee_id FROM employees m
WHERE m.last_name ='K_ing');
#进阶8:分页查询/*
应用场景:当要显示的数据一页显示不全,需要分页提交sql请求
语法:
SELECT 查询列表
from 表明
【join type join 表】
on 连接条件
where 筛选条件
group by 分组字段
having 分组后的筛选
order by 排序字段
limit offset,size
offset:要显示条目的起始索引(起始索引从0开始)
size:要显示的条目个数
特点:
1、limit语句放在查询语句的最后
2、公式
要显示的页数 page,每页的条目数size
SELECT 查询列表
from 表名
limit (page-1)*size,size
size=10
page
1 0
2 10
3 20
*/#案例1 :查询前5条员工信息SELECT*FROM employees LIMIT0,5;#案例2:查询第11条到第25条员工信息SELECT*FROM employees LIMIT10,15;#案例3:有奖金,并且工资排在前10名的员工信息SELECT*FROM employees
WHERE commission_pct ISNOTNULLORDERBY salary DESCLIMIT0,10;#查询所有是领导的员工的姓名SELECT last_name FROM employees
WHERE employee_id IN(SELECT manager_id FROM employees
);#练习#1.查询工资最低的员工信息:last_name,salarySELECT last_name,salary FROM employees
WHERE salary =(SELECTMIN(salary)FROM employees
);#2.查询平均工资最低的部门信息#方式1:SELECT*FROM departments
WHERE department_id =(SELECT department_id FROM employees e
GROUPBY e.department_id
orderbyAVG(salary)ASCLIMIT1);#方式2:SELECTAVG(salary),department_id FROM employees
GROUPBY department_id;SELECTMIN(ag)FROM(SELECTAVG(salary) ag,department_id FROM employees
GROUPBY department_id
) agg;SELECT d.*FROM departments d
WHERE d.department_id =(SELECT department_id
FROM employees
GROUPBY department_id
HAVINGAVG(salary)=(SELECTMIN(ag)FROM(SELECTAVG(salary) ag,department_id FROM employees
GROUPBY department_id
) agg
));#3.查询平均工资最低的部门信息和该部门的平均工资SELECT d.*,ag
FROM departments d
INNERJOIN(SELECTAVG(salary) ag,department_id
FROM employees
GROUPBY department_id
ORDERBYAVG(salary)ASCLIMIT1) agg
on agg.department_id = d.department_id;#4.查询平均工资最高的 job 信息SELECT j.*FROM jobs j
WHERE j.job_id =(SELECT job_id FROM employees
GROUPBY job_id
orderbyAVG(salary)DESCLIMIT1);#5.查询平均工资高于公司平均工资的部门有哪些SELECT department_id,avg(salary)FROM employees
GROUPBY department_id
HAVINGAVG(salary)>(SELECTAVG(salary)FROM employees
);#6.查询公司中所有manager的详细信息SELECT e.*FROM employees e
WHERE e.employee_id IN(SELECT employee_id FROM employees
WHERE employee_id IN(SELECT manager_id FROM employees
));#7.各部门中 最高工资中最低的那个部门的最低工资是多少SELECTMIN(salary)FROM employees
WHERE department_id =(SELECT department_id FROM employees
GROUPBY department_id
ORDERBYMAX(salary)descLIMIT1);#8.查询平均工资最高的部门的manager的详细信息:SELECT
last_name,d.department_id,email,salary
FROM employees e
INNERJOIN departments d
ON d.manager_id = e.employee_id
WHERE d.department_id =(SELECT department_id FROM employees
GROUPBY department_id
ORDERBYAVG(salary)DESCLIMIT1);
#进阶9:联合查询/*
union:将多条查询语句的结果合并成一个结果
语法:
查询语句1
UNION
查询语句2
WHERE
应用场景:
当要查询的结果来自多个表,且多个表之间没有连接关系,且查询的结果一样。
特点:
1.要求多条查询语句的查询列数是一致的
2.要求多条查询语句顺序是一致的
3.会自动去重 用ALL可以取消去重
*/#引入的案例:查询部门编号>90或邮箱包含a的员工信息SELECT*FROM employees
WHERE department_id >90OR email like'%a%';SELECT*FROM employees WHERE email LIKE'%a%'UNIONSELECT*FROM employees WHERE department_id >90;
7 DML
#DML语句/*
数据操作语言
插入:insert
修改:update
删除:delete
*/#一、插入语句/*
方式一:
语法:
表明
列名
值
insert into 表名(列名...) values(值1,..);
方式二:
insert into 表名
set 列名=值,列名=值,...
*/#1.插入的值类型要与列的类型一致或兼容INSERTINTO beauty(id,`name`,sex,borndate,phone,photo,boyfriend_id)VALUES(13,'古力娜扎','女','1994-1-7','122222222',NULL,2);SELECT*FROM beauty;#2.可以为NULL的列是如何插入值的INSERTINTO beauty(id,`name`,sex,borndate,phone,boyfriend_id)VALUES(14,'唐艺昕','女','1984-1-7','144444444',3);SELECT*FROM beauty;#3.列的顺序可以颠倒,列和值的数量一定要匹配,可以省略列名INSERTINTO beauty
VALUES(18,'张飞','男',NULL,'119',NULL,NULL);#两种方式大pk#1、方式一:支持插入多行;方式二:不支持#2、方式一:支持子查询;方式二:不支持insertinto beauty(id,`name`,phone)SELECT26,'宋茜','11809866';#二、修改语句 /*
1.修改单表的记录
语法:
UPDATE 表明
SET 列=新值,...
WHERE 筛选条件
2.修改多表的记录【补充】
语法:
sql92语法:
update 表1 别名, 表2 别名
set 列=值...
WHERE 连接条件
AND 筛选条件;
sql99语法:
update 表明 别名
【inner left right】 join 表2 别名
on 连接条件
set 列=值...
WHERE 筛选条件;
*/#案例1:修改beauty表中姓唐的女神的电话为13899888899UPDATE beauty
SET phone ='13899888899'WHERE`name`LIKE'唐%';#2.修改多表的记录#案例1:修改张无忌的女朋友的手机号为115UPDATE beauty b
INNERJOIN boys bo
ON b.boyfriend_id = bo.id
set phone='115'WHERE b.boyfriend_id =1;#案例2:修改没有男朋友的女神的男朋友编号都为2号UPDATE boys
SET boyName ='张飞',userCP =10WHERE id =2;SELECT*FROM boys;UPDATE beauty b
LEFTJOIN boys bo
ON b.boyfriend_id = bo.id
SET b.boyfriend_id =2WHERE b.boyfriend_id ISNULL;#删除语句/*
方式一:delete
语法:
1.单表删除
delete from 表名 WHERE 筛选条件
2.多表删除
sql92语法
delete 表1的别名,表2的别名
from 表1 别名,表2 别名
where 连接条件
and 筛选条件
sql99语法
delete 表1的别名,表2的别名
FROM 表1 别名
[inner,left,right] JOIN 表2 别名
ON 连接条件
WHERE 筛选条件
方式二:truncate
语法:truncate table 表名;
*/#方式一:delete#1.单表的删除#案例1:删除手机号以9结尾的女神信息DELETEFROM beauty WHERE phone LIKE'%9';#2.多表删除#案例:删除张无忌女朋友的信息delete b
FROM beauty b
JOIN boys bo
ON b.boyfriend_id = bo.id
WHERE b.boyfriend_id =1;#方式二:truncate#案例:将魅力值>100的男神信息删除TRUNCATETABLE boys WHERE userCP >100;#delete pk truncate/*
1.delete 可以加where 条件,truncate不能加
2.truncate删除,效率高一丢丢
3.假如要删除的列表中有自增长列,如果用delete删除后,再插入数据,自增长的值从断点开始,而truncate删除后,再插入数据,自增长列的值从1开始。
4.truncate没有返回值,delete有
5.truncate删除不能回滚,delete删除可以回滚
*/