MySQL服务的启动和停止
方式一:计算机——右击管理——服务
方式二:通过管理员身份运行
net start 服务名(启动服务)
net stop 服务名(停止服务)
MySQL服务的登录和退出
方式一:通过mysql自带的客户端
只限于root用户
方式二:通过windows自带的客户端
登录:
mysql 【-h主机名 -P端口号 】-u用户名 -p密码
退出:
exit或ctrl+C
MySQL的常见命令
1.查看当前所有的数据库
show databases;
2.打开指定的库
use 库名
3.查看当前库的所有表
show tables;
4.查看其它库的所有表
show tables from 库名;
5.创建表
create table 表名(
列名 列类型,
列名 列类型,
。。。
);
6.查看表结构
desc 表名;
7.查看服务器的版本
方式一:登录到mysql服务端
select version();
方式二:没有登录到mysql服务端
mysql --version
或
mysql --V
MySQL的语法规范
1.不区分大小写,但建议关键字大写,表名、列名小写
2.每条命令最好用分号结尾
3.每条命令根据需要,可以进行缩进 或换行
4.注释
单行注释:#注释文字
单行注释:-- 注释文字
多行注释:/* 注释文字 */
SQL的语言分类
DQL(Data Query Language):数据查询语言
select
DML(Data Manipulate Language):数据操作语言
insert 、update、delete
DDL(Data Define Languge):数据定义语言
create、drop、alter
TCL(Transaction Control Language):事务控制语言
commit、rollback
SQL的常见命令
show databases; 查看所有的数据库
use 库名; 打开指定 的库
show tables ; 显示库中的所有表
show tables from 库名;显示指定库中的所有表
create table 表名(
字段名 字段类型,
字段名 字段类型
); 创建表
desc 表名; 查看指定表的结构
select * from 表名;显示表中的所有数据
进阶1:基础查询
语法:
SELECT 要查询的东西
【FROM 表名】;
类似于Java中 :System.out.println(要打印的东西);
特点:
①通过select查询完的结果 ,是一个虚拟的表格,不是真实存在
②要查询的东西 可以是常量值、可以是表达式、可以是字段、可以是函数
1.查询单个字段
SELECT 字段名 FROM 表名;
2.查询多个字段
SELECT 字段名,字段名 FROM 表名;
3.查询所有字段
SELECT * FROM 表名;
4.查询常量
SELECT 常量值;
注意:字符型和日期型的常量值必须用单引号引起来,数值型不需要
5.查询函数
SELECT 函数名(实参列表);
6.查询表达式
SELECT 100/1234;
7.起别名
① as
② 空格
8.去重
SELECT DISTINCT 字段名 FROM 表名;
9. +
作用:做加法运算
SELECT 数值+数值:直接运算
SELECT 字符+数值:先试图将字符转换成数值,如果转换成功,则继续运算;否则转换成0,再做运算
SELECT NULL+值:结果都为null
10. concat函数
功能:拼接字符
SELECT CONCAT(字符1,字符2,字符3.....)
11.IFNULL函数
功能:判断某字段或表达式是否为NULL,如果为NULL,返回指定的值,否则返回原本的值
SELECT IFNULL(commission_pct,0) FROM employees;
12.ISNULL函数
功能:判断某字段或表达式是否为NULL,如果是,则返回1,否则返回0
进阶2:条件查询
条件查询:根据条件过滤原始表的数据,查询到想要的数据
语法:
select
要查询的字段|表达式|常量值|函数
from
表
where
条件 ;
分类:
一、条件表达式
示例:salary>10000
条件运算符:
> < >= <= = != <>
Eg.
#案例一:查询工资>12000的员工信息
SELECT
*
FROM
employees
WHERE
salary > 12000;
#案例二:查询部门编号不等于90号的员工名和部门编号
SELECT
last_name,
department_id
FROM
employees
WHERE
department_id<>90;
二、逻辑表达式
示例:salary>10000 && salary<20000
逻辑运算符:
and(&&):两个条件如果同时成立,结果为true,否则为false
or(||):两个条件只要有一个成立,结果为true,否则为false
not(!):如果条件成立,则not后为false,否则为true
Eg.
#案例一:查询工资在10000到20000之间的员工名、工资以及奖金
SELECT
last_name,
salary,
commission_pct
FROM
employees
WHERE
salary>=10000 AND salary<=20000;
#案例二:查询部门编号不是在90到110之间,或者工资高于15000的员工信息
SELECT
*
FROM
employees
WHERE
department_id<90 OR department_id>110 OR salary>15000;
三、模糊查询
like
特点:
①一般和通配符搭配使用
通配符:
% 任意多个字符,包含0个字符
_ 任意单个字符
Eg.
#1. like
#案例一:查询员工名中包含字符a的员工信息
SELECT *
FROM
employees
WHERE
last_name LIKE '%a%';
#案例二:查询员工名中第三个字符为e,第五个字符为a的员工名和工资
SELECT
last_name,
salary
FROM
employees
WHERE
last_name LIKE '__e_a%';
#案例三:查询员工名中第二个字符为_的员工名
SELECT
last_name
FROM
employees
WHERE
last_name LIKE '_$_%' ESCAPE '$';
between and
①使用between and可以提高语句的见简洁度
②包含临界值
③两个临界值不要调换顺序
Eg.
#案例一:查询员工编号在100到120之间的员工信息
SELECT
*
FROM
employees
WHERE
employee_id BETWEEN 100 AND 120;
in
含义:判断某字段的值是否属于in列表中的某一项
特点:
①使用in提高语句简洁度
②in列表的值类型必须一致
③不支持通配符
Eg.
#案例:查询员工的工种编号是 IT_PROG、AD_VP、AD_PRES中的一个员工名和工种编号
SELECT
last_name.
job_id
FROM
employees
WHERE
job_id IN ('IT_PROG','AD_VP','AD_PRES');
is null
=或<>不能用于判断NULL值
#案例一:查询没有奖金的员工名和奖金率
SELECT
last_name,
commission_pct
FROM
employees
WHERE
commission_pct IS NULL;
安全等于 <=>
SELECT
last_name,
commission_pct
FROM
employees
WHERE
commission_pct <=> NULL;
SELECT
last_name,
salary
FROM
employees
WHERE
salary <=> 12000;
进阶3:排序查询
语法:
select
要查询的东西
from
表
where
条件
order by 排序的字段|表达式|函数|别名 【asc(升序)|desc(降序)】
特点:
1.ASC代表的是升序,DESC代表的是降序,默认为升序
2.ORDER BY子句中可以支持单个字段、多个字段、表达式、函数、别名
3.ORDER BY子句一般是放在查询语句的最后面,LIMIT子句除外
Eg.
#案例1:查询员工信息,要求工资从高到低排序
SELECT
*
FROM
employees
ORDER BY
salary DESC;
SELECT
*
FROM
employees
ORDER BY
salary ASC;
#案例二:查询部门编号>=90的员工信息,按入职时间的先后进行排序【添加筛选条件】
SELECT *
FROM employees
WHERE department_id>=90
ORDER BY hiredate ASC;
#案例三:按年薪的高低显示员工的信息和年薪【按表达式排序】
SELECT *,salary*12*(1+IFNULL(commission_pct,0)) 年薪
FROM employees
ORDER BY salary*12*(1+IFNULL(commission_pct,0)) DESC;
#案例四:按年薪的高低显示员工的信息和年薪【按别名排序】
SELECT *,salary*12*(1+IFNULL(commission_pct,0)) 年薪
FROM employees
ORDER BY 年薪 DESC;
#案例五:按姓名的长度显示员工的姓名和工资【按函数排序】
SELECT LENGTH(last_name) 字节长度,last_name,salary
FROM employees
ORDER BY LENGTH(last_name) DESC;
#案例六:查询员工信息,要求先按工资排序,再按员工编号排序【按多个字段排序】
SELECT *
FROM employees
ORDER BY salary ASC, employee_id DESC;
进阶4:常见函数
含义:类似Java的方法,将一组逻辑语句封装在方法体中,对外暴露方法名
优势:1.隐藏了实现细节 2.提高了代码的重用性
调用:SELECT 函数名(实参列表) FROM 表;
分类: 1.单行函数
如concat、length、ifnull等
2.分组函数
功能:做统计使用,又称为统计函数、聚合函数、组函数
一、单行函数
1、字符函数
concat拼接
substr截取子串
upper转换成大写
lower转换成小写
trim去前后指定的空格和字符
ltrim去左边空格
rtrim去右边空格
replace替换
lpad左填充
rpad右填充
instr返回子串第一次出现的索引
length 获取字节个数
Eg.
#1.length 获取参数值的字节个数
SELECT LENGTH('john');
SELECT LENGTH('张三丰');
SHOW VARIABLES LIKE '&char&'
#2.concat拼接字符
SELECT CONCAT(last_name,'_',first_name) 姓名 FROM employees;
#3.upper、lower
SELECT UPPER('john');
SELECT LOWER('john');
#实例:将姓变大写,名变小写,然后拼接
SELECT CONCAT(UPPER(last_name),LOWER(first_name)) 姓名 FROM employees;
#4.substr、substring
SELECT SUBSTR('小明去上学',3); out_put;
#截取从指定索引处指定的字符长度的字符
SELECT SUBSTR('小明去上学',1,4); out_put;
#案例:姓名中首字符大写,其他字符小写然后用_拼接
SELECT CONCAT(UPPER(SUBSTR(last_name,1,1)),'_',LOWER(SUBSTR(last_name,2))) output
FROM employees;
#5.instr
#返回字串起始索引
SELECT INSTR('我爱北京天安门','天安门') AS output;
#6.trim
SELECT LENGTH(TRIM(' 北京 ')) AS output;
SELECT TRIM('a' FROM 'aaaaa北京aaa') AS output;
#7.lpad
SELECT LPAD('天安门',10,'*') AS output;
#8.rpad
SELECT RPAD('天安门',10,'*') AS output;
#9.replace
SELECT REPLACE('我爱北京天安门','天安门','故宫') AS output;
2、数学函数
round 四舍五入
rand 随机数
floor向下取整
ceil向上取整
mod取余
truncate截断
Eg.
#round 四舍五入
SELECT ROUND(1.65);
SELECT ROUND(1.567,2);
#ceil向上取整,返回>=该参数的最小整数
SELECT CEIL(1.02);
#floor 向下取整
SELECT FLOOR(-9.99);
#truncate 截断
SELECT TRUNCATE(1.699999,1);
#mod 取余
#MOD(a,b) : a-a/b*b
SELECT MOD(10,3);
SELECT 10%3;
3、日期函数
now当前系统日期+时间
curdate当前系统日期
curtime当前系统时间
str_to_date 将字符转换成日期
date_format将日期转换成字符
Eg.
#now
SELECT NOW();
#curdate
SELECT CURDATE();
#curtime
SELECT CURTIME();
#可以获取指定的部分的年、月、日、小时、分钟、秒
SELECT YEAR(NOW()) 年;
SELECT YEAR('1997-2-5') 年;
#str_to_date
SELECT STR_TO_DATE('1998-3-2','%Y-%c-%d') AS output;
#查询入职日期为1992-4-3的员工信息
SELECT * FROM employees WHERE hiredate = '1992-4-3';
#date_format
SELECT DATE_FORMAT(NOW(),'%y年%m月%d日') AS output;
4、流程控制函数
if 处理双分支
case语句 处理多分支
情况1:处理等值判断
情况2:处理条件判断
Eg.
#1.if函数
SELECT IF(10>5,'大','小');
#2.case函数的使用一:swithch case的效果
/*
案例:查询员工的工资,
部门号=30,显示工资为1.1倍
部门号=40,显示工资为1.2倍
部门号=50,显示工资为1.3倍
其他部门显示为原工资
*/
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级别
否则,显示D级别
*/
SELECT salary,
CASE
WHEN salary>20000 THEN 'A'
WHEN salary>15000 THEN 'B'
WHEN salary>10000 THEN 'C'
ELSE 'D'
END AS 工资级别
FROM employees;
5、其他函数
version版本
database当前库
user当前连接用户
SELECT VERSION();
SELECT DATABASE();
SELECT USER();
二、分组函数
sum 求和
max 最大值
min 最小值
avg 平均值
count 计数
特点:
1、以上五个分组函数都忽略null值,除了count(*)
2、sum和avg一般用于处理数值型
max、min、count可以处理任何数据类型
3、都可以搭配distinct使用,用于统计去重后的结果
4、count的参数可以支持:
字段、*、常量值,一般放1
建议使用 count(*)
Eg.
#1.简单使用
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;
SELECT SUM(salary),AVG(salary),MIN(salary),MAX(salary),COUNT(salary)
FROM employees;
#2.参数支持类型
SELECT SUM(last_name),AVG(last_name) FROM employees;
SELECT MAX(last_name),MIN(last_name) FROM employees;
#3.是否忽略null
SELECT COUNT(commission_pct) FROM employees;
SELECT commission_pct FROM employees;
#4.和distinct搭配
SELECT SUM(DISTINCT salary),SUM(salary) FROM employees;
#5.count函数
SELECT COUNT(salary) FROM employees;
SELECT COUNT(*) FROM employees;
SELECT COUNT(1) FROM employees;
效率:
MYISAM存储引擎下,COUNT(*)的效率高
INNODB存储引擎下,COUNT(*)和COUNT(1)的效率相似,比COUNT(字段)高
进阶5:分组查询
语法:
select 查询的字段,分组函数
from 表
group by 分组的字段
特点:
1、可以按单个字段分组
2、和分组函数一同查询的字段最好是分组后的字段
3、分组筛选条件分为两类
数据源 位置 关键字
分组前筛选: 原始表 group by的前面 where
分组后筛选: 分组后的结果集 group by的后面 having
4、可以按多个字段分组,字段之间用逗号隔开
5、可以支持排序
6、having后可以支持别名
Eg.
#案例一:查询每个工种的最高工资
SELECT MAX(salary),job_id
FROM employees
GROUP BY job_id;
#案例二:查询每个位置上的部门个数
SELECT COUNT(*),location_id
FROM departments
GROUP BY location_id;
#添加筛选条件
#案例一:查询邮箱中包含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;
#添加复杂的筛选条件
#案例一:查询那个部门的员工个数>2
#①查询每个部门的员工个数
SELECT COUNT(*),department_id
FROM employees
GROUP BY department_id;
#②根据①的结果进行筛选,查询那个部门的员工个数>2
SELECT COUNT(*),department_id
FROM employees
GROUP BY department_id
HAVING COUNT(*)>2;
#案例二:查询每个工种有奖金的员工的最高工资>12000的工种编号和最高工资
#①查询每个工种有奖金的员工的最高工资
SELECT MAX(salary),job_id
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id;
#②根据①的结果进行筛选,最高工资>12000
SELECT MAX(salary),job_id
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id
HAVING MAX(salary)>12000;
#案例三:查询领导编号>102的每个领导手下的最低工资>5000的领导编号是哪个,以及其最低工资
#①查询每个领导手下的员工固定最低工资
SELECT MIN(salary),manager_id
FROM employees
GROUP BY manager_id
#②添加筛选条件:编号>102
SELECT MIN(salary),manager_id
FROM employees
WHERE manager_id>102
GROUP BY manager_id
#③添加筛选条件:最低工资>5000
SELECT MIN(salary),manager_id
FROM employees
GROUP BY manager_id
HAVING MIN(salary)>5000;
#按表达式或函数分组
#案例:按员工姓名的长度分组,查询每一组的员工个数,筛选员工个数>5的
#①查询每个长度的员工个数
SELECT COUNT(*),LENGTH(last_name) len_name
FROM employees
GROUP BY LENGTH(last_name);
#②添加筛选条件
SELECT COUNT(*),LENGTH(last_name)
FROM employees
GROUP BY LENGTH(last_name)
HAVING COUNT(*)>5;
#按多个字段分组
#案例:查询每个部门每个工种的员工的平均工资
SELECT AVG(salary),department_id,job_id
FROM employees
GROUP BY job_id,department_id;
#添加排序
#案例:查询每个部门每个工种的员工的平均工资,并且按平均工资的高低显示
SELECT AVG(salary),department_id,job_id
FROM employees
WHERE department_id IS NOT NULL
GROUP BY job_id,department_id
ORDER BY AVG(salary) DESC;
进阶6:多表连接查询
笛卡尔乘积:如果连接条件省略或无效则会出现
解决办法:添加上连接条件
一、sql92标准
传统模式下的连接 :等值连接——非等值连接
1.等值连接的结果 = 多个表的交集
2.n表连接,至少需要n-1个连接条件
3.多个表不分主次,没有顺序要求
4.一般为表起别名,提高阅读性和性能(起了别名就不能用原先的名字)
Eg.
#1、等值连接
#案例一:查询女生名和男生名
SELECT name,boyName
FROM boys,beauty
WHERE beauty.borndate = boys.id;
#案例二:查询员工名和对应的部门名
SELECT last_name,department_name
FROM employees,departments
WHERE employees.department_id = departments.department_id;
#2、为表起别名
#查询员工名、工种号、工种名
SELECT e.last_name,e.job_id,e.job_title
FROM employees e,jobs j
WHERE e.job_id = j.job_id;
#3、两个表的顺序可以调换
#查询员工名、工种号、工种名
SELECT e.last_name,e.job_id,j.job_title
FROM jobs j,employees e
WHERE e.job_id = j.job_id;
#4、加筛选
#案例一:查询有奖金的员工名、部门名
SELECT last_name,department_name
FROM employees e,departments d
WHERE e.department_id = d.department_id
AND e.commission_pct IS NOT null;
#案例二:查询城市名中第二个字符为o的部门名和城市名
SELECT department_name,city
FROM departments d,locations l
WHERE d.location_id = l.location_id
AND city LIKE '_o%';
#5、加分组
#案例一:查询每个城市的部门个数
SELECT COUNT(*) 个数, city
FROM departments d,locations l
WHERE d.location_id = l.location_id
GROUP BY city
#案例二:查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资
SELECT department_name,d.manager_id,MIN(salary)
FROM departments d,employees e
WHERE d.department_id = e.department_id
and commission_pct IS NOT NULL
GROUP BY department_name,d.manager_id;
#6、加排序
#案例:查询每个工种的工种名和员工的个数,并按员工个数降序
SELECT job_title,COUNT(*)
FROM employees e, jobs j
WHERE e.job_id = j.job_id
GROUP BY job_title
ORDER BY COUNT(*) DESC;
#7、实现三表连接
#案例:查询员工名、部门名和所在的城市
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
AND city LIKE 's%';
二、sql99语法:通过join关键字实现连接
含义:1999年推出的sql语法
支持:
等值连接、非等值连接、自连接 (内连接)
外连接:左外连接、右外连接、全外连接(MySQL不支持)
交叉连接
语法:
select 字段,...
from 表1
【inner|left outer|right outer|cross】join 表2 on 连接条件
【inner|left outer|right outer|cross】join 表3 on 连接条件
【where 筛选条件】
【group by 分组字段】
【having 分组后的筛选条件】
【order by 排序的字段或表达式】
好处:语句上,连接条件和筛选条件实现了分离,简洁明了!
Eg.
#2、非等值连接
#案例一:查询员工的工资和工资级别
SELECT salary,grade_level
FROM employees e, job_grades g
WHERE salary BETWEEN g.lowest_sal AND g.highest_sal
AND g.grade_level = 'A';
三、自连接
sql99
语法:
SELECT 查询列表
FROM 表1 别名 【连接类型】
JOIN 表2 别名 ON 连接条件
WHERE 筛选条件
Eg.
#一、内连接
/*
语法:
SELECT 查询列表
FROM 表1 别名
INNER JOIN 表2 别名
ON 连接条件;
分类:
等值
非等值
自连接
*/
#1、等值连接
#案例一:查询员工名、部门名
SELECT last_name,department_name
from employees e
INNER JOIN departments d
ON e.department_id = d.department_id;
#案例二:查询名字中包含e的员工名和工种名(筛选)
SELECT last_name,job_title
FROM employees e
INNER JOIN jobs j
ON e.job_id = j.job_id
WHERE e.last_name LIKE '%e%';
#案例三:查询部门个数大于3的城市名和部门个数(分组+筛选)
SELECT city, COUNT(*) 部门个数
FROM departments d
INNER JOIN locations l
ON d.location_id = l.location_id
GROUP BY city
HAVING COUNT(*)>3;
#案例四:查询那个部门的部门员工个数大于3的部门名和员工个数,并按个数排序(排序)
SELECT COUNT(*) 个数, department_name
FROM employees e
INNER JOIN departments d
ON e.department_id = d.department_id
GROUP BY department_name
HAVING COUNT(*)>3
ORDER BY COUNT(*) DESC;
#案例五:查询员工名、部门名、工种名,并按部门名降序
SELECT last_name,department_name,job_title
FROM employees e
INNER JOIN departments d ON e.department_id = d.department_id
INNER JOIN jobs j ON e.job_id = j.job_id
ORDER BY department_name DESC;
#二、非等值连接
#查询员工的工资级别
SELECT salary,grade_level
FROM employees e
JOIN job_grades g
ON e.salary BETWEEN g.lowest_sal AND g.highest_sal;
#查询工资级别的个数>2的个数,并且按工资级别降序
SELECT COUNT(*),grade_level
FROM employees e
JOIN job_grades g
ON e.salary BETWEEN g.lowest_sal AND g.highest_sal
GROUP BY grade_level
HAVING COUNT(*)>20
ORDER BY grade_level DESC;
#三、自连接
#查询姓名中包含k的员工的名字、上级的名字
SELECT e.last_name,m.last_name
FROM employees e
JOIN employees m
ON e.manager_id = m.employee_id
WHERE e.last_name LIKE '%k%';
#左外连接
SELECT b.*,bo.*
FROM boys bo
LEFT OUTER JOIN beauty b
ON b.boyfriend_id = bo.id
WHERE b.id IS NULL;
#案例一:查询哪个部门没有员工
#左外
SELECT d.*, e.employee_id
FROM departments d
LEFT OUTER JOIN employees e
ON d.department_id = e.department_id
WHERE e.employee_id IS NULL;
#右外
SELECT d.*, e.employee_id
FROM employees e
RIGHT OUTER JOIN departments d
ON d.department_id = e.department_id
WHERE e.employee_id IS NULL;
#全外
SELECT b.*,bo.*
FROM beauty b
FULL OUTER JOIN boys bo
ON b.boyfriend_id = bo.id;
#交叉连接
SELECT b.*,bo.*
FROM beauty b
CROSS JOIN boys bo;
SELECT e.last_name,m.last_name
FROM employees e
JOIN employees m ON e.`manager_id`=m.`employee_id`;
sql92
SELECT e.last_name,m.last_name
FROM employees e,employees m
WHERE e.`manager_id`=m.`employee_id`;
进阶7:子查询
含义:
一条查询语句中又嵌套了另一条完整的select语句,其中被嵌套的select语句,称为子查询或内查询
在外面的查询语句,称为主查询或外查询
特点:
1、子查询都放在小括号内
2、子查询可以放在from后面、select后面、where后面、having后面,但一般放在条件的右侧
3、子查询优先于主查询执行,主查询使用了子查询的执行结果
4、子查询根据查询结果的行数不同分为以下两类:
① 单行子查询
结果集只有一行
一般搭配单行操作符使用:> < = <> >= <=
非法使用子查询的情况:
a、子查询的结果为一组值
b、子查询的结果为空
② 多行子查询
结果集有多行
一般搭配多行操作符使用:any、all、in、not in
in: 属于子查询结果中的任意一个就行
any和all往往可以用其他查询代替
Eg.
#一、WHERE或having后面
#1.标量子查询
#案例一:谁的工资比Abel高
SELECT *
FROM employees
WHERE salary>(
SELECT salary
FROM employees
WHERE last_name = 'Abel'
);
#案例二:返回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
);
#案例三:返回公司工资最少的员工的last_name,job_id和salary
SELECT last_name,job_id,salary
FROM employees
WHERE salary = (
SELECT MIN(salary)
FROM employees
);
#案例四:查询最低工资大于50号部门最低工资的部门id和其最低工资
SELECT department_id,MIN(salary)
FROM employees
GROUP BY department_id
HAVING MIN(salary)>(
SELECT MIN(salary)
FROM employees
WHERE department_id = 50
);
#2.列子查询(多行子查询)
#案例一:返回location_id是1400或1700的部门中的所有员工姓名
SELECT last_name
FROM employees
WHERE department_id IN(
SELECT DISTINCT department_id
FROM departments
WHERE location_id IN(1400,1700)
)
#案例二:返回其他部门中比job_id为IT_PROG部门任一工资低的员工的员工号、姓名、job_id以及salary
SELECT last_name,employee_id,job_id,salary
FROM employees
WHERE salary<ANY(
SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'
) AND job_id<>'IT_PROG';
#案例三:返回其他部门中比job_id为IT_PROG部门所有工资都低的员工的员工号、姓名、job_id以及salary
SELECT last_name,employee_id,job_id,salary
FROM employees
WHERE salary<ALL(
SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'
) AND job_id<>'IT_PROG';
#3、行子查询
#案例:查询员工编号最小并且工资最高的员工信息
SELECT *
FROM employees
WHERE (employee_id, salary) = (
SELECT MIN(employee_id),MAX(salary)
FROM employees
);
SELECT *
FROM employees
WHERE employee_id=(
SELECT MIN(employee_id)
FROM employees
) AND salary=(
SELECT MAX(salary)
FROM employees
);
#二、select后面
#案例:查询每个部门的员工个数
SELECT d.*,(
SELECT COUNT(*)
FROM employees e
WHERE e.department_id = d.department_id
) 个数
FROM departments d;
#案例二:查询员工号=102的部门名
SELECT (
SELECT department_name
FROM departments d
INNER JOIN employees e
ON d.department_id = e.department_id
WHERE e.employee_id = 102
) 部门名;
#三、from后面
#案例:查询每个部门的平均工资的工资等级
SELECT ag_dep.*,g.grade_level
FROM (
SELECT AVG(salary),department_id
FROM employees
GROUP BY department_id
) ag_dep
INNER JOIN job_grades g
on ag_dep.ag BETWEEN lowest_sal AND highest_sal;
#四、exists后面(相关子查询)
#案例一:查询有员工的部门名
SELECT department_name
FROM departments d
WHERE EXISTS(
SELECT *
FROM employees e
WHERE d.department_id = e.department_id
);
进阶8:分页查询
应用场景:
实际的web项目中需要根据用户的需求提交对应的分页查询的sql语句
语法:
select 字段|表达式,...
from 表
【where 条件】
【group by 分组字段】
【having 条件】
【order by 排序的字段】
limit 【起始的条目索引,】条目数;
特点:
1.起始条目索引从0开始
2.limit子句放在查询语句的最后
3.公式:select * from 表 limit (page-1)*sizePerPage,sizePerPage
假如:
每页显示条目数sizePerPage
要显示的页数 page
Eg.
#分页查询
#案例一:查询前五条员工信息
SELECT *
FROM employees
LIMIT 0,5;
#案例二:查询地11条-第25条
SELECT *
FROM employees
LIMIT 10,15;
#案例三:有奖金的员工信息,工资较高的前10名显示
SELECT *
FROM employees
WHERE commission_pct IS NOT NULL
ORDER BY salary DESC
LIMIT 10;
进阶9:联合查询
引入:
union 联合、合并
语法:
select 字段|常量|表达式|函数 【from 表】 【where 条件】 union 【all】
select 字段|常量|表达式|函数 【from 表】 【where 条件】 union 【all】
select 字段|常量|表达式|函数 【from 表】 【where 条件】 union 【all】
.....
select 字段|常量|表达式|函数 【from 表】 【where 条件】
特点:
1、多条查询语句的查询的列数必须是一致的
2、多条查询语句的查询的列的类型几乎相同
3、union代表去重,union all代表不去重
Eg.
#联合查询
#案例:查询部门编号>90或邮箱包含a的员工信息
SELECT *
FROM employees
WHERE email LIKE '%a%' OR department_id>90;
SELECT * FROM employees WHERE email LIKE '%a%'
UNION
SELECT * FROM employees WHERE department_id>90;