尚硅谷李玉婷老师MySQL课程--DQL语言

DQL(Data Query Language):数据查询语言 select

1.基础查询

语法:
SELECT 查询列表 【FROM 表名】;

类似于Java中 :System.out.println(要打印的东西);
特点:
1.通过select查询完的结果 ,是一个虚拟的表格,不是真实存在
2.要查询的东西 可以是常量值、可以是表达式、可以是字段、可以是函数
3.使用前需打开指定的数据库

// 1. 查询表中单个字段
SELECT last_name FROM employees;
// 2. 查询表中多个字段,查询列表用逗号隔开,顺序无要求
SELECT last_name,salary,email FROM employees;
// 3. 查询表中所有字段
SELECT * FROM employees;
// 4.查询常量值
SELECT 100;
SELECT 'James';
// 5. 查询表达式
SELECT 6*23;
// 6. 查询函数
SELECT VERSION();
// 7. 起别名
//①便于理解 ②利用别名区分字段重名
//方式一:
SELECT last_name AS 姓;
SELECT first_name AS 名;
//方式二:
SELECT last_name 姓;
SELECT first_name 名;
// 8. 去重(DISTINCT)
SELECT  DISTINCT department_id FROM emplyees;
// 9. '+'的作用
/*
	mysql中只有一个功能:运算符
	select 100+90;	两个都为数值型,做加法运算
	select ’123‘+90;   一方为字符型,试图将字符型数值转换成数值型。
								如果转换成功,则继续做加法运算
	select ’John‘+90; 如果转换失败,则将字符型数值转换成0
	select null+10;		只要其中一方为null,则结果肯定为null
*/
//查询员工名和姓连接成一个字段,并显示为姓名,用空格隔开。(关键字CONCAT)
SELECT CONCAT (last_name,' ',first_name) AS 姓名 FROM employees;

2.条件查询

条件查询:根据条件过滤原始表的数据,查询到想要的数据

语法:

SELECT 
	要查询的字段|表达式|常量值|函数
FROM 
	表
WHERE 
	条件 ;
分类:
一、条件表达式
示例:salary>10000

条件运算符:

大于,小于: > < >= <=   
等于: =   
不等于: != <>
二、逻辑表达式
示例:salary>10000 && salary<20000

逻辑运算符:

AND(&&):两个条件如果同时成立,结果为true,否则为false
OR(||):两个条件只要有一个成立,结果为true,否则为false
NOT(!):如果条件成立,则not后为false,否则为true
三、模糊查询
示例:last_name like 'a%'
关键词:like, between and, in, is null

1.like
特点:
① 一般和通配符搭配使用
%:任意多给字符
_:任意单个字符

例1:查询员工包含字符a的员工名

SELECT last_name
FROM employees
WHERE last_name
LIKE '%a%';

例2:查询员工名中第二个字符为_的员工名(ESCAPE)

SELECT last_name
FROM employees
WHERE last_name
LIKE '_\_%';
或者指明转义符
SELECT last_name
FROM employees
WHERE last_name
LIKE '_$_%' ESCAPE '$';

2.between and
① 使用between and 包含边界值
② 两个临界值不可颠倒顺序

例1:查询员工编号在100到120之间的员工名

SELECT last_name
FROM employees
WHERE employee_id
BETWEEN 100 AND 120;

3.in
判断某字段的值是否属于in列表中的某一项
① 比使用OR提高语句简洁度
② IN列表里的值必须一致或兼容
③ 不支持%的使用

例1:查询员工的工种编号是IT_PROG, AD_VP, AD_PRES中的一个员工名和工种编号

SELECT last_name
FROM employees
WHERE job_id
IN ('IT_PROG', 'AD_VP', 'AD_PRES');

4.is null / is not null
①=, <, >不能用于判断null
② is 只能判断null,= 只能判断数值, 安全等于 <=> 都可判断,但可读性较低

例1:查询没有奖金的员工名

SELECT last_name FROM employees WHERE commission_pct IS NULL;

3.排序查询

语法:

SELECT
	要查询的东西
FROM
	表
WHERE 
	条件
ORDER BY 排序的字段|表达式|函数|别名 【asc/desc】

① asc/desc – 升序/降序,默认为asc升序
② order by子句一般是放在查询语句的最后面,limit子句除外

例1:查询员工信息,要求工资从高到低排序

SELECT * FROM employees ORDERS BY salary DESC;

例2:查询部门编号>=90的员工信息,按入职时间的先后

SELECT * FROM employees WHERE department_id>=90 ORDER BY hiredate ASC;

例3:按年薪的高低显示员工的信息和年薪【按别名排序】

SELECT *, salary*12*(1+IFMULL(commission_pct,0)) 年薪 
FROM employees ORDER BY  salary*12*(1+IFMULL(commission_pct,0)) DESC;

SELECT *, salary*12*(1+IFMULL(commission_pct,0)) 年薪 
FROM employees ORDER BY 年薪 DESC;

例4:按姓名的长度显示员工的姓名和工资【按函数排序】

SELECT LENGTH(last_name) 字节长度, lastname, salary
FROM employees ORDER BY LENGTH(last_name) DESC;

例5:查询员工信息,先按工资升序,再按员工编号降序【按多个字段排序】

SELECT * FROM employees ORDER BY salary ASC, employee_id DESC;

4.常见函数

好处

1.隐藏了实现细节
2.提高代码的重用性

调用

SELECT 函数名(实参列表) 【from 表】

一、单行函数

1、字符函数
concat(str1,str2)		拼接
substr(str,pos)			截取pos开始子串
substr(str,pos,len)		截取pos开始,长度为len子串
instr(str,substr)		返回子串第一次出现的索引
upper(str)				转换成大写
lower(str)				转换成小写
trim(str)				去前后指定的空格
trim(char,str)			去前后指定的字符
ltrim					去左边空格
rtrim					去右边空格
replace(str,from_str,to_str)
						替换
lpad(str,len,padstr)	用指定字符左填充实现指定长度
rpad					用指定字符右填充实现指定长度
length(str) 			获取字节个数
2、数学函数
round 			四舍五入
rand 			随机数
floor			向下取整
ceil			向上取整
mod				取余
truncate		截断		truncate(1.699,2) 结果为1.69
3、日期函数
now				当前系统日期+时间
curdate			当前系统日期
curtime			当前系统时间
str_to_date 	将字符转换成日期
	str_to_date('9-13-1999','%m-%d-%Y')		结果为1999-9-13
date_format		将日期转换成字符
	date_format('2018/6/6','%Y年%m月%d日')	结果为2018年6月6日
4、流程控制函数
if 				处理双分支
	if(5>10,'大','小');
	
case使用一:处理等值判断
case 要判断的字段或表达式
when  常量1  then  要显示的值1或语句1
when  常量2  then  要显示的值2或语句2
...
else  要显示的值n或语句n
end

case使用二:处理条件判断,相当于多重if
case
when  条件1  then 要显示的值1或语句1
when  条件2  then  要显示的值2或语句2
...
else  要显示的值n或语句n
end
5、其他函数
version			版本
database		当前库
user			当前连接用户

二、分组函数

功能:做统计使用

sum 			求和
max 			最大值
min 			最小值
avg 			平均值
count 			计数

SELECT SUM(salary) FROM employees;
SELECT SUM(salary), AVG(salary), MAX(salary), MIN(salary) FROM employees;

特点:
*

	1、以上五个分组函数都忽略null值,除了count(*)
	2、sum和avg一般用于处理数值型,max、min、count可以处理任何数据类型
    3、都可以搭配distinct使用,用于统计去重后的结果
	4、count的参数可以支持:
		(1) 字段  (2)*,表示全部行  (3) 常量值,一般放1,表示行数
		建议使用 count(*),效率更高
	5、和分组函数一同查询的字段要求是group by后的字段

5.分组查询

语法:

select 查询的字段,分组函数
from 表
【where 条件】
group by 分组的字段
【order by 字段】

​ 特点:
​ 1、可以按单个字段分组
​ 2、和分组函数一同查询的字段最好是分组后的字段
​ 3、分组筛选

针对的表位置关键字
分组前筛选:原始表group by的前面where
分组后筛选: 分组后的结果集group by的后面having

​ 4、可以按多个字段分组,字段之间用逗号隔开。多个字段均相同为一组
​ 5、可以支持排序
​ 6、having后可以支持别名

例1:查询每个部门的平均工资

SELECT AVG(salary) FROM employees;

例2:查询每个工种的最高工资

SELECT MAX(salary), job_id FROM employees GROUP BY job_id;

例3:查询每个位置上的部门个数

SELECT COUNT(*), location_id FROM departments GROUP BY location_id;

添加筛选条件
例3:查询邮箱中包含a字符的,每个部门的平均工资

SELECT AVG(salary), department_id
FROM employees
WHERE email LIKE ‘%a%’
BROUP BY department_id;

添加分组前的筛选条件
例4: 查询有奖金的每个领导手下员工的最高工资

SELECT MAX(salary), manager_id
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY manager_id;

添加分组后的筛选条件
例5:查询哪个部门的员工个数>2

(1) 查询每个部门的员工个数
SELECT COUNT(*), department_id
From employees
GROUP BY department_id;
(2) 根据(1)的结果进行筛选,查询哪个部门的员工个数>2
SELECT COUNT(*), department_id
FROM employees
GROUP BY department_id
HAVING COUNT(*)>2;

例6:查询每个工种有奖金的员工的最高工资>12000的工种编号和最高工资

(1) 查询每个工种有奖金的员工的最高工资
SELECT MAX(salary), job_id
FROM employees
GROUP BY job_id

6.多表连接查询

含义:

又称多表查询,当查询的字段来自于多个表时,就会用到连接查询
笛卡尔乘积现象:表1 m行,表2 n行,结果m*n行

发生原因:没有有效连接条件
避免方法:添加有效连接条件

SELECT name, boyName FROM boys, beauty
WHERE beauty.boyfriend_id=boys.id;
分类

按年代分

  • sql92标准:仅支持内连接
  • sql99标准:支持内连接+外连接(全外连接除外)+交叉连接

按功能分

  • 内连接

    • 等值连接
    • 非等值连接
    • 自连接
  • 外连接

    • 左外连接
    • 右外连接
    • 全外连接
  • 交叉连接

一、sql92标准

1.等值连接

注:

  1. 字段重名有歧义时,添加表名限定。如:employees.department_id
  2. 一般需要为表起别名。起别名后必须使用别名,不能使用原始表名
  3. 表的顺序可以调换
  4. 可以添加筛选、分组和排序
  5. 可以实现多表连接。n表连接至少需要n-1个连接条件

例1:查询员工名和对应的部门名

SELECT last_name,department_name
FROM employees,departments
WHERE employees.department_id=departments.department_id;

例2:查询员工名、工种号、工种名

SELECT last_name,e.job_id,job_title
FROM employees e,jobs j
WHERE e.job_id=j.job_id;

例3:查询有奖金的员工名、部门名(添加筛选)

SELECT last_name,department_name
FROM employees e,jobs j
WHERE e.department_id=d.department_id;
AND e.commission_pct IS NOT NULL;

例4:查询每个城市的部门个数(添加分组)

SELECT COUNT(*) 个数,city
FROM departments d,locations l
WHERE d.location_id=l.location_id
GROUP BY city;

例5:查询每个工种的工种名和员工的个数,并且按员工个数降序(添加排序)

SELECT job_title,COUNT(*)
FROM jobs j,employees e
WHERE j.job_id=e.job_id
GROUP BY job_title
ORDER BY COUNT(*) DESC;

例6:查询员工名、部门名和所在的城市(三表连接)

SELECT last_name,department_name,city
FROM employee e,departments d,locations l
WHERE e.department_id=d.department_id
AND d.location_id=l.location_id;
2.非等值连接

例1:查询员工和工资级别

SELECT salary,grade_level
FROM employees e,job_grades g
WHERE salary BETWEEN g.lowest_sal AND g.highest_sal
3.自连接

一张表看作多张表连接

例1:查询员工名和上级的名称

SELECT e.employee_id,e.last_name,m.employee_id,m.last_name,
FROM employees e,employees m
WHERE e.employee_id=m.employee_id;

二、sql99标准

语法

SELECT 查询列表
FROM 表1 别名1
【连接类型:内连接、外连接、交叉连接】 JOIN 表2 别名2
ON 连接条件
【筛选、分组、排序】

分类

  • 内连接(INNER)
  • 外连接(OUTER)
    • 左外(LEFT 【OUTER】)
    • 右外(RIGHT 【OUTER】)
    • 全外(FULL 【OUTER】)
  • 交叉连接(CROSS)
1.内连接
SELECT 查询列表
FROM 表1 别名1
INNER JOIN 表2 别名2
ON 连接条件
【筛选、分组、排序】
(1) 等值连接(可添加分组筛选排序)

例1:查询员工名、部门名

SELECT last_name,department_name
FROM employees e
INNER JOIN departments d
ON e.department_id=d.department_id; 
(2) 非等值连接(可添加分组筛选排序)

例1:查询员工工资级别个数>20的个数,并且按工资级别排序

SELECT COUNT(*),grade_level
FROM employees e
INNER 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;
(3) 自连接

例:查询名字包含字符k的员工、上级的名字

SELECT e.last_name,m.last_name
FROM employees e
INNER JOIN employees m
ON e.manager_id=m.employee_id
WHERE e.last_name LIKE '%k%';
2.外连接

用于查询一个表有另一个表没有的记录
特点:

  1. 外连接的查询结果为主表中的所有记录
    如果从表中有和它匹配的,显示匹配的值
    如果从表中没有和它匹配的,显示NULL
    外连接查询结果=内连接结果+主表中有二从表中没有的记录
  2. 左外连接:left join左边的是主表
    右外连接:right join右边的是主表

例1:查询男朋友不在男神表的女神名

//左外连接
SELECT g.name
FROM girls g
LEFT OUTER JOIN boys b
ON g.boyfriend = b.id
WHERE g.id IS NULL;
	
//右外连接
SELECT g.name
FROM boys b
RIGHT OUTER JOIN girls g
ON g.boyfriend = b.id
WHERE g.id IS NULL;

例2:查询哪个部门没有员工

SELECT d.* 
FROM departments d
LEFT OUTER JOIN employees e
ON  d.departments_id = e.departments_id
WHERE e.employee_id IS NULL;
3.交叉连接

笛卡尔乘积

总结

在这里插入图片描述
在这里插入图片描述

7.子查询

  1. 含义:出现在其他语句中的select语句,成为子查询或内查询

  2. 分类:
    按子查询出现的位置:

    • select 后面 👉 仅支持标量子查询
    • from后面 👉 支持表子查询
    • where后面或having后面 ★
      标量子查询 ✔
      列子查询 ✔
      行子查询(较少)
    • exists后面(相关子查询) 👉

    按结果集的行列数不同

    • 标量子查询/单行子查询(结果集只有一行一列)
    • 列子查询/多行子查询(一列多行)
    • 行子查询(一般为一行多列,也可为多行多列)
    • 表子查询(一般为多行多列)
一、where/having后面

特点

  1. 子查询放在小括号内
  2. 子查询一般放在条件的右侧
  3. 标量子查询一般搭配单行操作符使用
    列子查询一般搭配多行操作符使用 in, any/some, all
  4. 子查询的执行优先主查询
1. 标量子查询/单行子查询

例1:谁的工资比Abel高

//(1)查询Able的工资
SELECT salary
FROM employees
WHERE last_name = 'Abel';

//2.查询员工信息,满足salary>(1)结果
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和salary

SELECT last_name,job_id,salary
FROM employees
WHERE salary=(
	SELECT  MIN(salary)
	FROM employees
);

例4:查询最低工资大于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. 列子查询/多行子查询

返回多行
使用多行比较操作符(IN/NOT IN, ANY|SOME, ALL)

操作符含义
IN/NOT IN等于列表中的任意一个
ANY/SOME和子查询返回的某一个值作比较
ALL和子查询返回的所有值作比较

例1:查询location_id是1400或1700的部门中的所有员工姓名

SELECT last_name
FROM employees
WHERE department_id IN(
	SELECT department_id
	FROM departments
	WHERE location_id=1400 OR 1700;
)

例2:返回其他工种中比job_id为’IT_PROG’工种任意工资低的员工的员工号、姓名、job_id以及salary

SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary< ANY(
	SELECT DISTINCT salary
	FROM employees
	WHERE job_id='IT_PROG'
)AND job_id<>'IT_PROG';
//或
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary< (
	SELECT MAX(salary)
	FROM employees
	WHERE job_id='IT_PROG'
)AND job_id<>'IT_PROG';

例3:返回其他工种中比job_id为’IT_PROG’工种所以工资低的员工的员工号、姓名、job_id以及salary

SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary< ALL(
	SELECT DISTINCT salary
	FROM employees
	WHERE job_id='IT_PROG'
)AND job_id<>'IT_PROG';
//或
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary< (
	SELECT MIN(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后面

例1:查询每个部门的员工个数

SELECT d.*,(
	SELECT COUNT(*)
	FROM employees e
	WHERE e.department_id=d.department_id
) 个数
FROM departments d;

例2:查询员工号为102的部门名

SELECT (
	SELECT department_name
	FROM departments
	INNER JOIN employees e
	ON d.department_id=e.department_id
	WHERE e.employee_id=102
) 部门名;
三、from后面

查询结果充当一张表,必须起别名

例:查询每个部门的平均工资的工资等级

//(1)查询每个部门的平均工资
SELECT AVG(salary),department_id
FROM employees
GROUP BY department_id

//(2)连接(1)的结果集和job_grades表,筛选条件平均工资between lowest and highest
SELECT avg_dep.*g,grade_level,
FROM (
	SELECT AVG(salary) avg_sal,department_id
	FROM employees
	GROUP BY department_id
) avg_dep
INNER JOIN job_grade g
ON avg_dep.avg_sal BETWEEN g.lowest_sal AND g.highest_sal;
四、exists后面(相关子查询)

语法
exists(完整的查询语句)
结果:1/0

例1:查询有员工的部门名

SELECT department_name
FROM departments d
WHERE EXISTS(
	SELECT *
	FROM employees e
	WHERE e.department_id=d.department_id
);
//可以用IN的方式代替
SELECT department_name
FROM departments d
WHERE d.department_id IN(
	SELECT department_id
	FROM employees
)

例2:查询没有女朋友的男神信息

SELECT boyName
FROM boys b
WHERE NOT EXISTS(
	SELECT *
	FROM beauty g
	WHERE g.boyfriend_id=b.id
);

8.分页查询

语法

SELECT 查询列表
FROM 表
【连接、筛选、分组、排序】
limit offset,size;
//offset: 要显示条目的起始索引(从0开始,若为0可省略)
//size: 要显示的条目个数

特点

  1. limit语句放在查询语句的最后
  2. 公式
    要显示的页数page,每页的条目数size
    limit size*(page-1),size

例1:查询前五条员工信息

SELECT * FROM employees LIMIT 0,5;

例2:查询有奖金的员工信息,并且工资较高的前十名

SELECT *
FROM employees
WHERE commision_pct IS NOT NULL
ORDER BY salary DESC
LIMIT 10;

9.联合查询(union)

将多条查询语句的结果合并为一个结果
语法

查询语句1
union
查询语句2
union
...

应用
要查询的结果来自于多个表且多个表没有直接的连接关系,但查询的信息一致

特点

  1. 要求多条查询语句的查询列数是一致的
  2. 要求多条查询语句查询的每一列的类型和顺序最好一致
  3. union关键字默认去重。如果使用union all,可以包含重复项

例:查询中国用户中男性的信息以及外国用户中男性的信息

SELECT id,cName,cSex FROM t_ca WHERE cSex='男'
UNION
SELECT t_id,tName,tGender FROM t_ua WHERE tGender='male'; 
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值