DQL——数据查询语言

目录

一.基础查询

1.1 查询表中的字段

1.1.1 查询表中的单个字段

1.1.2 查询表中的多个字段

1.1.3 查询表中的所有字段

1.2 查询常量值

1.3 查询表达式

1.4 查询函数

1.5 为字段起别名以及为表起别名

1.5.1 为字段起别名

1.5.2 为表起别名

1.6 去重

1.7 拼接字段,并按显示为新字段

1.7.1区别于 +号的使用

1.8  IFNULL(expr1,expr2)

二.条件查询

2.1 按条件表达式筛选

2.2 按逻辑表达式筛选

2.3 模糊查询

三. 排序查询

四. 常见函数

4.1 字符函数

4.1.1 LENGTH(str)

4.1.2  CONCAT(str1,str2,...)

4.1.3 UPPER(str)

4.1.4  LOWER(str)

4.1.5 SUBSTR(str FROM pos FOR len) 或 SUBSTRING(str FROM pos FOR len)

4.1.6 INSTR(str,substr)

4.1.7 TRIM([remstr FROM] str)

4.1.8 LPAD(str,len,padstr)

4.1.9 RPAD(str,len,padstr)

4.1.10 REPLACE(str,from_str,to_str)

4.2 数学函数

4.2.1 ROUND(X) 或 ROUND(X,D)

4.2.2 CEIL(X)

4.2.3 FLOOR(X)

4.2.4 TRUNCATE(X,D)

4.2.5 MOD(N,M)

4.2.6 DATEDIFF(expr1,expr2)

4.3 日期函数

4.3.1 NOW()

4.3.2 CURDATE()

4.3.3 CURTIME()

4.3.4 年月日时分秒

4.3.5 STR_TO_DATE(str,format)

4.3.6 DATE_FORMAT(date,format)

4.4 其他函数

4.5 流程控制函数

4.5.1 IF(expr1,expr2,expr3) 函数

4.5.2 CASE函数

五. 分组函数

5.1 SUM(expr)  或 SUM([DISTINCT] expr)

5.2 AVG([DISTINCT] expr)

5.3 MAX(expr)

5.4 MIN(expr)

5.5 COUNT(DISTINCT expr,[expr...])  或 COUNT(expr)

六 .分组查询

七 .连接查询

7.1 sql92标准

7.1.1 等值连接

7.1.2 非等值连接

7.1.3 自连接

7.2 sql99标准

7.2.1 内连接(同sql92标准)​

7.2.2 外连接

7.2.3 交叉连接

八. 子查询

8.1 where或having后面

8.1.1 标量子查询

8.1.2 列子查询

8.1.3 行子查询

8.2 select后面

8.3 from后面

8.4 exists后面(相关子查询)

九 . 分页查询

十 . union联合查询

十一. 查询语句总结


一.基础查询

语法: select 查询列表 from 表名;

特点:

  1. 查询列表可以是 : 表中的字段,常量值,表达式,函数
  2. 查询的结果是一个虚拟的表格

1.1 查询表中的字段

1.1.1 查询表中的单个字段

SELECT 字段名 FROM 表名;

1.1.2 查询表中的多个字段

SELECT 字段名,字段名,字段名,... FROM 表名;

1.1.3 查询表中的所有字段

SELECT * FROM 表名;

1.2 查询常量值

SELECT 常量值;

1.3 查询表达式

SELECT 表达式;

如:

DQL——数据查询语言_第1张图片

1.4 查询函数

SELECT 函数;

如:

DQL——数据查询语言_第2张图片

1.5 为字段起别名以及为表起别名

1.5.1 为字段起别名

注:起别名最好加上引号,防止与关键字或其他特殊字符冲突而报错

SELECT 常量值/表达式/函数 As 别名;

#或

SELECT 字段名 As 别名,字段名 As 别名...FROM 表名;

#简写

SELECT 字段名 别名,字段名 别名...FROM 表名;

如:DQL——数据查询语言_第3张图片

DQL——数据查询语言_第4张图片

1.5.2 为表起别名

注意:如果为表起了别名,则查询字段就不能用原来的表名去限定

 如:查询员工的姓名,工号,工作名称

DQL——数据查询语言_第5张图片

1.6 去重

SELECT DISTINCT 字段名 FROM 表名;

1.7 拼接字段,并按显示为新字段

SELECT CONCAT(字段名,字段名,字段名,...) AS 别名 FROM 表名;

DQL——数据查询语言_第6张图片

1.7.1区别于 +号的使用

作用:仅仅作为运算符使用

  1. SELECT 10+10; 两个操作数都为数值型,则做加法运算
  2. SELECT “10” +10; 两个操作数,其中一个是字符型数据,另一个是数值型数据,则尝试将字符型数据转换为数值型数据,若转换成功,按转换的数值继续做加法运算
  3. SELECT  “abc”+10; 两个操作数,其中一个是字符型数据,另一个是数值型数据,则尝试将字符型数据转换为数值型数据,若转换失败,则将字符型数据转换成0,再做加法运算。
  4. SELECT null+10; 只要有一方为null,则结果必为null

1.8  IFNULL(expr1,expr2)

作用:用于判断expr1字段的值是否为null

expr2:若expr1字段的值为null时想要显示的值

如要显示某表的全部列,各列之间用逗号连接,并将此连接列重新命名为out_put  

DQL——数据查询语言_第7张图片

二.条件查询

语法:

SELECT
	查询的字段名 
FROM
	表名 
WHERE
	筛选条件;

分类

  1. 按条件表达式筛选 即条件运算符 >   <    =      !=     >=     <=    <>     <=>
  2. 按逻辑表达式筛选  即逻辑运算符 与或非  &&     ||     !     and    or    not
  3. 模糊查询 即 like            between and          in              is null

2.1 按条件表达式筛选

如 查询工资>12000 的员工信息

SELECT
	* 
FROM
	employees 
WHERE
	salary > 12000;

DQL——数据查询语言_第8张图片

2.2 按逻辑表达式筛选

作用:用于连接条件表达式

&&  或 and 两个条件都为True,结果为True,反之为False
|| 或 or 只要有一个条件为True,结果就位True,反之为False
! 或 not 本身为True,结果就为False,本身为False,结果就为True

如:查询工资在10000到20000之间到员工的姓名,工资,以及奖金

SELECT
	CONCAT( first_name, last_name ) AS 姓名,
	salary,
	IFNULL( commission_pct, 0 )* salary AS 奖金 
FROM
	employees 
WHERE
	salary >= 10000 
	AND salary <= 20000;

DQL——数据查询语言_第9张图片

2.3 模糊查询

like

一般和通配符搭配使用

  1.  % 表示任意多个字符,包含0个字符
  2. _ 表示任意单个字符
  3. 转义字符 \ 如    \- 表示 _
between and

between a and b

在a和b之间

既包含a又包含b 即包含临界值

in

判断某字段是否是包含在in的列表里

注:in列表的值类型必须统一

is null 或 not null 判断是否为null,是null则为True  仅仅可以判断null值,区别于<=>
is not null 判断是否为null
<=>

安全等于,相当于C语言的==

既可以用于判断null值,又可以判断普通的数值,字符等类型

<> 安全不等于,相当于C语言的!=

例一:查询员工的名中包含字符a的员工信息(like的使用)

SELECT
	* 
FROM
	employees 
WHERE
	last_name LIKE "%a%";

例二:查询员工的姓名中包含字符_的员工的信息(like的使用)

指定转义字符 ESCAPE

SELECT
	* 
FROM
	employees 
WHERE
	last_name LIKE "%\_%";



#或


	
SELECT
	* 
FROM
	employees 
WHERE
	last_name LIKE "%$_%" ESCAPE "$";#指定$为转义字符

例三:查询员工的工种编号是 AD_PRES,AD_VP,FI_MGR的员工信息(in的使用)

#查询员工的工种编号是 AD_PRES,AD_VP,FI_MGR的员工信息
SELECT
	* 
FROM
	employees 
WHERE
	job_id IN ( 'AD_PRES', 'AD_VP', 'FI_MGR' );

例四:#查询没有奖金的员工的信息(is null的使用)

#查询没有奖金的员工的信息
SELECT
	* 
FROM
	employees 
WHERE
	commission_pct IS NULL

三. 排序查询

语法:

SELECT
	查询列表 
FROM
	表名
【WHERE
	筛选条件】 
ORDER BY
	排序列表 【 ASC | DESC】

ASC:从低到高,升序排序

DESC:从高到低,降序排序

默认为升序排序,即ASC

特点:

  1. order by 支持单个字段,多个字段,表达式,函数,别名等的排序
  2. order by一般放在查询语句的末尾,但limit除外

例一:查询员工信息,要求工资按从高到低排序(简单排序)

#查询员工信息,要求工资按从高到低排序
SELECT
	* 
FROM
	employees 
ORDER BY
	salary DESC;

示例二 :查询部门编号大于等于90的员工信息,要求按入职的先后顺序进行排序(添加筛选条件的排序)

#查询部门编号大于等于90的员工信息,要求按入职的先后顺序进行排序
SELECT
	* 
FROM
	employees 
WHERE
	department_id >= 90 
ORDER BY
	hiredate ASC;

例三:按员工年薪从低到高显示员工信息和年薪 (按表达式排序)

#按员工年薪从低到高显示员工信息和年薪
SELECT *, salary * 12 *( IFNULL( commission_pct, 0 )+ 1 ) AS "年薪" 
FROM
	employees 
ORDER BY
	年薪 ASC;

例四:按员工的姓名长度升序排序,要求显示员工姓名和薪资(按函数排序)

	
#按员工的姓名长度升序排序,要求显示员工姓名和薪资
SELECT 
last_name,
LENGTH(last_name) AS "名字长度",
salary
FROM
employees
ORDER BY
LENGTH(last_name) ASC;

例五:查询员工信息,先按工资降序排序,再按员工编号升序排序(多重排序)

#查询员工信息,先按工资降序排序,再按员工编号升序排序
SELECT
	* 
FROM
	employees 
ORDER BY
	salary DESC,
	employee_id ASC;

四. 常见函数

语法:

SELECT
	函数名 (参数) 
【 FROM
	表名】;

优点:

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

分类:

  1. 单行函数 如:concat,length,ifnull等
  2. 分组函数 是用来做与统计有关的,所以又称为统计函数,聚合函数,组函数  如:

4.1 字符函数

4.1.1 LENGTH(str)

功能:用于统计参数值的字节个数

DQL——数据查询语言_第10张图片

4.1.2  CONCAT(str1,str2,...)

功能:用于字段的拼接,字符串的拼接

DQL——数据查询语言_第11张图片

4.1.3 UPPER(str)

功能:将字符串中的英文转换为大写字母

DQL——数据查询语言_第12张图片

4.1.4  LOWER(str)

功能:将字符串中的英文转换为小写字母

DQL——数据查询语言_第13张图片

4.1.5 SUBSTR(str FROM pos FOR len) 或 SUBSTRING(str FROM pos FOR len)

功能:字符串的截取

  1. SUBSTR(str,int)  截取从指定索引处后面的所有字符
  2. SUBSTR(str,int,len) 截取指定字符从指定索引处开始的len个字符     如:截取   “我爱python“   中的   “我爱”       SELECT SUBSTR("我爱python",1,2); 或 SELECT SUBSTRING("我爱python" FROM 1 FOR 2);

注:索引值是从1开始的

DQL——数据查询语言_第14张图片

DQL——数据查询语言_第15张图片

4.1.6 INSTR(str,substr)

功能:返回子字符串(substr)在字符串(str)中第一次出现的起始索引值,若找不到则返回0

DQL——数据查询语言_第16张图片

4.1.7 TRIM([remstr FROM] str)

功能:去掉字符串前后指定的字符,默认为空格

DQL——数据查询语言_第17张图片

DQL——数据查询语言_第18张图片

4.1.8 LPAD(str,len,padstr)

功能:用指定的字符padstr,左填充str,使str的长度为指定的长度len

DQL——数据查询语言_第19张图片

4.1.9 RPAD(str,len,padstr)

功能:用指定的字符padstr,右填充str,使str的长度为指定的长度len

4.1.10 REPLACE(str,from_str,to_str)

功能:字符串的替换,即用to_str替换str中的from_str

DQL——数据查询语言_第20张图片

4.2 数学函数

4.2.1 ROUND(X) 或 ROUND(X,D)

功能:四舍五入,X:小数   D:保留几位小数

DQL——数据查询语言_第21张图片

DQL——数据查询语言_第22张图片

4.2.2 CEIL(X)

功能:向上取整。即返回大于等于该参数的最小整数

DQL——数据查询语言_第23张图片

4.2.3 FLOOR(X)

 功能:向下取整。即返回小于等于该参数的最小整数

DQL——数据查询语言_第24张图片

4.2.4 TRUNCATE(X,D)

功能:截断,即截取小数点后D位,区别于round(x)

DQL——数据查询语言_第25张图片

4.2.5 MOD(N,M)

功能:取余。即 N%M

DQL——数据查询语言_第26张图片

4.2.6 DATEDIFF(expr1,expr2)

功能:用于统计两个日期间隔的天数

DQL——数据查询语言_第27张图片

4.3 日期函数

4.3.1 NOW()

功能:返回当前系统的日期时间

DQL——数据查询语言_第28张图片

4.3.2 CURDATE()

功能:返回系统当前的日期

DQL——数据查询语言_第29张图片

4.3.3 CURTIME()

功能:返回系统当前的时间

DQL——数据查询语言_第30张图片

4.3.4 年月日时分秒

功能:

函数 描述 备注
YEAR(date)

MONTH(date) 

MONTHNAME(date)

MONTH(date) :返回数值月份

MONTHNAME(date):返回英文月份

DAY(date)
HOUR(time)
MINUTE(time)
SECOND(time)

4.3.5 STR_TO_DATE(str,format)

功能:将日期格式的字符转换为指定格式的日期

语法STR_TO_DATE("年符号1符号2日","%y符号1%m符号2%d")  要一一对应

格式符 描述 备注
%Y 4位的年份
%y 2位的年份
%m 月份(2位数的月份) 01,02,03...
%c 月份(小于10的月份用一位数表示) 1,2,3,4,5,6,7,8,9,10..
%d
%H 小时 24小时制
%h 小时 12小时制
%i 分钟
%s

DQL——数据查询语言_第31张图片

DQL——数据查询语言_第32张图片

 DQL——数据查询语言_第33张图片

4.3.6 DATE_FORMAT(date,format)

功能:将日期转换成字符串

DQL——数据查询语言_第34张图片

4.4 其他函数

VERSION() 查看数据库的版本
DATABASE() 查看当前所处的数据库
 USER() 查看当前的数据库登录用户

4.5 流程控制函数

4.5.1 IF(expr1,expr2,expr3) 函数

语法 if(条件,"true要显示的信息","false要显示的信息")

例一:添加一列备注,薪资大于12000的显示"哈哈哈哈"小于12000备注显示"呵呵"

SELECT
	last_name,
	salary,
IF
	( salary > 12000, "哈哈哈哈哈", "呵呵" ) AS "备注"
FROM
	employees;

DQL——数据查询语言_第35张图片

4.5.2 CASE函数

语法一:

case 要判断的字段或表达式

when 常量1 then 要显示的值1或语句1

when 常量2 then 要显示的值2或语句2

when 常量3 then 要显示的值3或语句3

...

else 要显示的值n语句n

end

例一:查询员工的工资,要求部门号为30,显示的工资为1.1倍;部门号为40的,显示的工资为1.2倍,部门号为50,显示的工资为1.3倍,其他为原工资

SELECT
	last_name,
	department_id,
	salary AS "原工资",
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;

DQL——数据查询语言_第36张图片

语法二:

case

when 条件1 then 要显示的值1或语句1

when 条件2 then 要显示的值2或语句2

when 条件3 then 要显示的值3或语句3

...

else 要显示的值n或语句n

end

列二:查询员工的薪资水平等级,要求薪资大于20000的为A级,薪资大于15000的为B级,薪资大于10000的为C级,其他为D级

SELECT
	first_name,
	salary,
CASE
		
		WHEN salary > 20000 THEN
		"A" 
		WHEN salary > 15000 THEN
		"B" 
		WHEN salary > 10000 THEN
		"C" ELSE "D" 
	END AS "工资等级"
	FROM
	employees;

DQL——数据查询语言_第37张图片

五. 分组函数

 功能:用于统计,所以又称为聚合函数,统计函数,组函数

特点:

  1. sum,avg一般用于处理数值型数据
  2. max,min,count可以处理任何类型数据
  3. 分组函数都忽略null值
  4. 可以和DISTINCT搭配使用,实现去重运算
  5. 一般使用count(*)来统计行数
  6. 和分组函数一同查询的字段要求是group by后的字段

5.1 SUM(expr)  或 SUM([DISTINCT] expr)

功能:求和某个字段  DISTINCT 剔除重复值再求和

注:忽略null

DQL——数据查询语言_第38张图片

5.2 AVG([DISTINCT] expr)

功能:求平均值,DISTINCT 剔除重复值的平均值

注:忽略null

DQL——数据查询语言_第39张图片DQL——数据查询语言_第40张图片

5.3 MAX(expr)

功能:求最大值

注:忽略null

DQL——数据查询语言_第41张图片

5.4 MIN(expr)

功能:求最小值 

注:忽略null

DQL——数据查询语言_第42张图片

5.5 COUNT(DISTINCT expr,[expr...])  或 COUNT(expr)

功能:统计个数,DISTINCT剔除重复出现的值   

注:只统计非空值  忽略null

 DQL——数据查询语言_第43张图片

用法① :统计非空的行数

SELECT COUNT(*) FROM employees;
SELECT COUNT(1) FROM employees;

#相当于新添加一列值全为1的列,然后统计该列的值的个数,1可以是其他任何字符串,数值

效率:

  1. 在MYISAM引擎中,COUNT(*)效率最高
  2. 在INNODB引擎中,COUNT(*),COUNT(1)效率差不多,比COUNT(字段名)效率要高

六 .分组查询

语法:

SELECT 
分组函数,字段(要求出现在group by的后面)
FROM 表名
【WHERE 筛选条件】
【GROUP BY 分组列表】
【ORDER BY 字段名 排序方式】;

特点:

  1. 分两种筛选  分组前筛选(数据源是原始表),分组后筛选(数据来源分组后的数据集)
  2. 分组函数做条件肯定是放在having子句里
  3. GROUP BY 支持单个字段,多个字段,别名

例一:查询每个工种的最高工资(分组前筛选)

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

例二:查询每个部门的平均工资(分组前筛选)

SELECT department_id,AVG(salary)
FROM employees
GROUP BY department_id;

例三:查询部门员工人数大于2的部门(分组后筛选)

SELECT department_id,COUNT(*)
FROM employees
GROUP BY department_id
HAVING COUNT(*)>2;

七 .连接查询

描述:连接查询又叫多表查询,当查询的字段来自多个表时,就会使用到连接查询

笛卡尔积现象:表1有m行,表2有n行,结果=m*n

发生原因:没有有效的连接条件

解决办法:添加有效的连接条件

分类:

(1)按年代分:

  1. sql92标准:仅仅只支持内连接
  2. sql99标准:推荐使用,支持 内连接+外连接(左外连接,右外连接)+交叉连接

(2)按功能分类

  1. 内连接:等值连接,非等值连接,自连接
  2. 外连接:左外连接,右外连接,全连接
  3. 交叉连接

7.1 sql92标准

7.1.1 等值连接

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

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

DQL——数据查询语言_第44张图片

例二:查询每个城市的部门个数

SELECT
	city,
	count(*) AS "部门个数" 
FROM
	departments AS d,
	locations AS l 
WHERE
	d.location_id = l.location_id 
GROUP BY
	city;

DQL——数据查询语言_第45张图片

例三:查询员工名,部门名,以及所在的城市(涉及三张表)


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;

DQL——数据查询语言_第46张图片

7.1.2 非等值连接

例一:查询员工的工资与工资等级

SELECT
	last_name,
	salary,
	grade_level 
FROM
	employees AS e,
	job_grades AS j 
WHERE
	salary > lowest_sal 
	AND salary <= hightest_sal;

DQL——数据查询语言_第47张图片

7.1.3 自连接

 自连接:同一张表至少查找两遍

例一:查询员工名与上级的名称

SELECT
	e.employee_id,
	e.last_name,
	m.employee_id AS "上级编号",
	m.last_name AS "上级姓名"
FROM
	employees AS e,
	employees AS m 
WHERE
	e.manager_id = m.employee_id;
	

DQL——数据查询语言_第48张图片

7.2 sql99标准

语法:

SELECT 查询列表
FROM 表1 【AS】 别名 
【连接类型】 JOIN 表2  【AS】 别名 
ON 连接条件
【WHERE 筛选条件】
【GROUP BY 分组】
【HAVING 筛选条件】
【ORDER BY 排序列表】; 

连接类型:

  1. 内连接:inner
  2. 外连接:左外连接(left 【outer】),右外连接(right 【outer】),全连接(full 【outer】)
  3. 交叉连接:cross 

7.2.1 内连接(同sql92标准)

语法:

SELECT 查询列表
FROM 表1 【AS】 别名 
INNER JOIN 表2  【AS】 别名 
ON 连接条件
【WHERE 筛选条件】
【GROUP BY 分组】
【HAVING 筛选条件】
【ORDER BY 排序列表】; 

特点:

  1. 可以添加筛选条件,分组条件,排序条件
  2. inner可以省略,默认为inner
  3. 筛选条件放在where后,连接条件放在on后,提高了分离性,增强了查询语句的可读性
  4. inner jion连接和sql92标准的等值连接在效果上是一致的,都是查询多表的交集

7.2.1.1 等值连接

例一: 查询员工名和部门名

SELECT
	last_name,
	department_name 
FROM
	employees AS e
	INNER JOIN departments AS d ON e.department_id = d.department_id;

DQL——数据查询语言_第49张图片

例二:查询名字中包含e的员工名和工种名

SELECT
	last_name,
	job_title 
FROM
	employees e
	INNER JOIN jobs AS j ON e.job_id = j.job_id 
WHERE
	last_name LIKE "%e%";

例三:查询部门个数大于3的城市名和部门个数

SELECT
	city,
	COUNT(*) AS "部门个数" 
FROM
	departments
	INNER JOIN locations ON departments.location_id = locations.location_id 
GROUP BY
	locations.city 
HAVING
	部门个数 > 3;

例四:查询部门员工个数大于等于3的部门名和员工个数,并按人数降序排序

SELECT
	department_name,
	COUNT(*) AS "员工个数" 
FROM
	employees e
	INNER JOIN departments d ON e.department_id = d.department_id 
GROUP BY
	e.department_id 
HAVING
	员工个数 >= 3 
ORDER BY
	员工个数 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;

7.2.1.2 非等值连接

例一:查询员工的工资等级

SELECT
	last_name,
	grade_level 
FROM
	employees e
	INNER JOIN job_grades AS jg ON e.salary BETWEEN jg.lowest_sal 
	AND jg.hightest_sal;

7.2.1.3 自连接

例一:查询员工的名字,和上级的名字

SELECT
	grade_level,
	COUNT(*) AS "薪资等级的个数" 
FROM
	employees e
	INNER JOIN job_grades AS jg ON e.salary BETWEEN jg.lowest_sal 
	AND jg.hightest_sal 
GROUP BY
	grade_level 
HAVING
	薪资等级的个数 > 20 
ORDER BY
	薪资等级的个数 DESC;

7.2.2 外连接

应用场景:常用于查询一个表中有,但另一个表中却没有记录的情况

区分主从表的方法:

  1. 左外连接,left join左边的是主表
  2. 右外连接,right join右边的是主表

特点:

  1. 外连接的查询结果为主表中的所有记录,如果从表中有和主表匹配的值,则显示匹配的值,若从表中没有和主表匹配的值,则显示null。即:外连接=内连接+主表有而从表没有的记录
  2. 左外和右外交换两个表的顺序,可以实现同样的效果

7.2.2.1 左外连接

例一:查询那个部门没有员工

SELECT d.department_name
FROM departments d
LEFT JOIN employees e
ON d.department_id = e.department_id
WHERE ISNULL(e.employee_id);

7.2.2.2 右外连接

例一:查询那个部门没有员工

SELECT d.department_name
FROM employees e
RIGHT JOIN departments d
ON e.department_id = d.department_id
WHERE ISNULL(e.employee_id);
	

7.2.2.3 全连接

实现的效果  全外连接 = 内连接的结果 + 表1中有但表2中没有 + 表1中没有但表2中有

7.2.3 交叉连接

实现效果 交叉连接 = 笛卡尔积的效果

SELECT
	d.*,
	l.* 
FROM
	departments d
	CROSS JOIN locations l;

DQL——数据查询语言_第50张图片

八. 子查询

含义:嵌套在其他语句内部的select语句,称为子查询或内查询,外面的语句可以是insert,update,delete,select等,一般select做为外部语句较为常用

内部嵌套其他select语句的查询,称为外查询或主查询

分类:

①按子查询出现的位置不同分类

  1. select后面:仅仅支持标量子查询

  2. from后面:支持表子查询

  3. where或having后面:支持标量子查询,列子查询,行子查询

  4. exists后面(相关子查询):支持标量子查询,列子查询,行子查询,表子查询

②按功能或结果集的行列数不同分类

  1. 标量子查询(单行子查询):结果集只有一行一列

  2. 列子查询:结果集只有一列多行

  3. 行子查询:结果集有一行多列

  4. 表子查询:结果集一般为多行多列

8.1 where或having后面

特点:

  1. 子查询放在小括号内
  2. 子查询一般放在条件的右侧
  3. 标量子查询,一般搭配着单行操作符使用 如:<  >    >=    <=    <>   <=>
  4. 列子查询,一般搭配搭配着多行操作符 如: in,any,some,all
  5. 子查询执行的优先级大于主查询
操作符 描述
in / not in 等于或不等于 列表中的任意一个
any / some 和子查询返回的某一个值比较
all  和子查询返回的所有值进行比较

8.1.1 标量子查询

例一:查询谁的工资比Abel高(where后)

SELECT
	last_name,
	salary 
FROM
	employees 
WHERE
	salary > ( SELECT salary FROM employees WHERE last_name = "Abel" );

例二:查询job_id与141号员工相同,salary比143号员工多的员工姓名,job_id,以及工资(多个子查询)(where后)

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 (分组查询) (where后)


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

例四:查询最低工资大于50号部门最低工资的部门id和其最低工资 (having后)

SELECT
	department_id,
	MIN( salary ) AS "部门最低薪资" 
FROM
	employees 
GROUP BY
	department_id 
HAVING
	部门最低薪资 > ( SELECT MIN( salary ) FROM employees WHERE department_id = 50 );

8.1.2 列子查询

例一:返回location_id是1400或1700的部门中的所有员工的姓名

SELECT
	last_name,
	department_id 
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
	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";

8.1.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 );
	
	

	

8.2 select后面

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

SELECT d.*,( SELECT COUNT(*) FROM employees e WHERE e.department_id = d.department_id ) AS "部门人数" 
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 )
	AS "部门名";

8.3 from后面

当做查询的数据来源  即:将子查询结果充当一张表,一般要取别名

例一:查询各部门的平均工资

SELECT
	各部门的平均工资.*,
	job_grades.grade_level 
FROM
	(
	SELECT
		department_name,
		AVG( salary ) AS 平均工资 
	FROM
		employees e
		LEFT JOIN departments d ON d.department_id = employee_id 
	GROUP BY
		d.department_id 
	) AS 各部门的平均工资
	INNER JOIN job_grades ON 各部门的平均工资.`平均工资` BETWEEN job_grades.lowest_sal 
	AND job_grades.hightest_sal;

8.4 exists后面(相关子查询)

语法:

exists(完整的查询语句)   返回的是bool类型,即有数据则返回1,无数据则返回0

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

SELECT
	department_name 
FROM
	departments 
WHERE
	EXISTS (
	SELECT
		* 
	FROM
		employees 
	WHERE
		departments.department_id = employees.department_id 
	);


/*等效于*/
SELECT
	department_name 
FROM
	departments 
WHERE
	department_id IN ( SELECT department_id FROM employees );

九 . 分页查询

应用场景:当要显示的数据一页无法全部显示的时候,需要分页提交sql请求

语法:

SELECT 查询的字段名列表
FROM 表名
【
连接类型 JOIN 表名
ON 连接条件
WHERE 筛选条件
GROUP BY 分组字段
HAVING 分组后的筛选条件
ORDER BY 排序字段 排序类型
】
LIMIT 【要显示的数据的起始行索引(起始索引从0开始)】,要显示的数据行数

特点:

  1. LIMIT语句放在查询语句的最后
  2. LIMIT (page-1)*size,size

例一:查询前五条的员工信息

SELECT *
FROM employees
LIMIT 0,5;


/*等价于*/

SELECT
	* 
FROM
	employees 
	LIMIT 5;

十 . union联合查询

功能:将多条查询语句的查询结果合并成一个结果

语法:

查询语句1

union

查询语句2

union

...

应用场景:

  1. 要查询的结果来自于多张表,且多张表没有直接的连接关系,但查询的信息一致时

特点:

  1. 要求多条查询语句的查询列数一致
  2. 要求多条查询语句的类一列的类型和顺序最好一致
  3. union默认去重,union all 不去重

例一:查询部门编号>90,或邮箱包含a的员工的信息

SELECT
	* 
FROM
	employees 
WHERE
	department_id > 90 UNION
SELECT
	* 
FROM
	employees 
WHERE
	email LIKE "%a%";


/*等价于*/
	
	
SELECT
	* 
FROM
	employees 
WHERE
	department_id > 90 
	OR email LIKE "%a%";

十一. 查询语句总结

DQL——数据查询语言_第51张图片

你可能感兴趣的:(MySql,sql,mysql)