SQL语句
SQL语句
目录
DQL数据查询语言
select * from demotable;,查看表数据
总概
SELECT标准示例
SELECT customer_id, last_name		-- 可为*
FROM customers  					-- 从表选择
WHERE customer_id = 1  				-- 筛选。布尔:()>NOT>AND>OR
ORDER BY first_name  				-- 按某列排序
LIMIT 10  							-- 仅显示前10条数据
 
--SELECT子句扩展(选择)
SELECT points + 10 AS points_factor	-- 构建新列。可输入表达式,若新列名有空格或中文可加引号
SELECT DISTINCT state  				-- 获得唯一值列表DQL语句及子句顺序
执行顺序补充
select		-- 5
from		-- 1
where		-- 2
group by	-- 3
having		-- 4
order by	-- 6
limit		-- 7SELECT扩展(跟在SELECT后的)
DISTINCT(去重)
- select后增加关键字
distinct即可- 例如:
SELECT DISTINCT state,获得唯一值列表 - 补充:DISTINCT只能出现在所有字段的最前面,后面接多个字段时为联合去重
 
 - 例如:
 
单行处理函数
使用
select (points+10) as points_factor,可输入表达式,若列名有空格可加引号select ifnull(comm,0) as comm from emp;,空处理函数
补充
- SQL中有NULL参与运算则结果一定为NULL,但空处理函数除外
 
分组函数(聚合函数 / 多行处理函数)
使用
select sum(sal) from mytable;,求总和select max(sal) from mytable;,找最高select min(sal) from mytable;,找最低select avg(sal) from mytable;,找平均select count(*) from mytable;,找总数
补充
- 分组函数,别名聚合函数,或多行处理函数(输入多行,输出一行)
 - SQL中有NULL参与运算则结果一定为NULL,但分组函数会自动忽略NULL
 - 分组函数不可直接在where子句中使用 
- 举例:即
select * from mytable where sal > avg(sal);错误。若要使用该功能,要使用嵌套查询 - 原因分析:执行顺序where > group by > select,在分组查询之前无法执行分组函数
 
 - 举例:即
 - 分组函数一般都会和GROUP BY分组查询联合使用,这也是其被称为分组函数的原因。若无group by则整个表为一组
 
分组类子语句(结合分组函数使用)
GROUP BY(分组查询)
使用
group by,按照某个字段或某些字段分组select max(sal) from emp group by job;,案例:找出每个工作岗位的最高薪资
补充
- ==【大坑】==当有group by时,select后面只能跟 “分组的字段” 以及 “分组函数”,其他不能跟!!! 
- 举例:不能
select ename,max(sal),job from emp group by job; - 第一个字段并不是最大值所对应的那一个!
 - 该语句在MySQL中能执行但结果无意义,在Oracle中甚至会报语法错误
 
 - 举例:不能
 - 多字段分组查询 
- 如
group by deptno,job(注意:先后顺序分重要) 
 - 如
 
HAVING(分组过滤)
使用
having,对分组之后的数据进行再次过滤
补充
- 和where差不多,但执行顺序不同,WHERE > GROUP BY > HAVING
 - WHERE和HAVING的选用:优先使用WHERE,除非WHERE搞不掂
 
筛选类子语句
WHERE(条件筛选)
除了查询以外,修改数据也能用
运算符
()					-- 括号运算符
>,<,=,>=,<=,><,!=	-- 比较运算符
NOT,AND,OR			-- 逻辑运算符
IS NULL		-- 匹配空值
IN			-- 列表包含,配合()使用
BETWEEN		-- 等同于:>= and <=
LIKE		-- 模糊匹配,配合%和_使用。若匹配%或_则使用转义符'\'
REGEXP		-- 正则匹配常用条件
WHERE birth_date >= '1990-01-01'  			 			-- 日期区间1
WHERE birth_date BETWEEN '1990-01-01' AND '2020-01-01' 	-- 日期区间2
WHERE phone IS NULL  									-- 匹配空值
WHERE state IN ('VA', 'FL', 'GA')						-- 列表包含
WHERE last_name LIKE 'b%'  								-- 模糊匹配,匹配b开头的对象,大小写无关
WHERE last_name LIKE 'b____'  							-- 模糊匹配,%任意匹配长度字符,下划线匹配单个字符正则匹配
WHERE last_name REGEXP 'field'  						-- 正则匹配,可组合特殊字符建立复杂筛选
'field'		包含
'^field'	以开头
'field$'	以结尾
'aa|bb'		并行
'[abcd]e'	单字符并行
'[a-d]e'	并行优化嵌套子查询
可以在where、from、select语句中使用子查询
where后:应用举例:找出薪资高于平均值的员工
WHERE client_id =(
	SELECT client_id
	FROM clients
	WHERE name = 'Myworks'
)from后:应用情况:查询结构作为一张新表
select后:这个不太好理解,大概可以代替下连接查询
连接类子语句(多表关联查询)
连接查询
- 概念 
- 实际开发中,大部分情况都不是从单表中查询数据,都是多表联合查询(考试也一般是多表联合查询)
 - 实际开发中,一般一个业务会对应多个表
 
 - 分类 
- 根据年代划分 
- SQL92(旧),一些老的DBA可能还在使用这种语法
 - SQL99(新)
 
 - 根据连接方式划分 
内连接(两张表没有主副之分,两张表平等)等值连接(连接条件是等量关系)非等值连接(连接条件是非等量关系)自连接(一张表看作两张表,自己连接自己)
外连接(分主表副表,主要查询主表数据,捎带查询副表。但副表没有与主表匹配的数据时,自动模拟NULL与之匹配)左外连接(左连接)(表示左边的表是主表,左右连接的写法可互转换)右外连接(右连接)(表示右边的表是主表,左右连接的写法可互转换)
全连接(不讲,很少用)
 
 - 根据年代划分 
 - 一些使用注意项 
- 连接查询原理、以及笛卡尔积现象(笛卡尔乘积现象) 
- 例如:
sekect ename,dname from emp,dept; - 说明:无条件限制时,则新表的数据量是两张表的记录的乘积。该现象为笛卡尔积现象
 - 避免:加条件过滤
 - 思考:避免笛卡尔积现象并不会减少记录的匹配次数,只不过现实的是有效记录,即不会提高查询效率
 
 - 例如:
 - 使用表的别名 
- 例如:
sekect e.ename,d.dname from emp e,dept d; - 说明:表的别名的好处:执行效率高、可读性好
 
 - 例如:
 
 - 连接查询原理、以及笛卡尔积现象(笛卡尔乘积现象) 
 
分类
内连接之等值连接
SQL92(太老,不用)
select
	e.ename,d.dname
from
	emp e,dept d
where
	e.deptno = d.deptnoSQL99(常用)
select
	e.ename,d.dname
from
	emp e
join			-- 这里可写成inner join,inner可省略,带inner目的是提高可读性
	dept d
on
	e.deptno = d.deptno- 特点:连接条件是等量关系
 - 案例:很常见,信息扩展
 - 比较 
- 看起来SQL92简单,但SQL99耦合度更低更清晰
 - SQL99可以使用WHERE进行过滤,而SQL92需要在WHERE使用AND(即表的连接条件和WHERE条件分离)
 
 
内连接之非等值连接
- 特点:连接条件是非等量关系
 - 案例:比如找出每个员工的工资等级(高中低)
 
内连接之自连接
- 特点:一张表看作两张表,自己连接自己
 - 案例:找出每个员工的上级领导的名字
 
外连接
- 特点:全量查询,不会丢数据
 
内连接
select
	a.ename '员工', b.ename '领导'
from
	emp a
join			-- 也可写成inner join,inner可省略
	emp b
on
	a.mgr = b.empno;左外连接
select
	a.ename '员工', b.ename '领导'
from
	emp a
left join		-- 表示左边是主表,也可写成left outer join,outer可省略
	emp b
on
	a.mgr = b.empno;右外连接
select
	a.ename '员工', b.ename '领导'
from
	emp b
right join		-- 表示右边是主表,也可写成right outer join,outer可省略
	emp a
on
	a.mgr = b.empno;三表联合查询
举例
select
	e.ename, d.name, s.grade
from
	emp e
join
	dept d
on
	e.deptno = de.deptno
join
	salgrade s
on
	e.sal between s.losal and s.hisal;结果编辑子语句
ORDER BY(排序)
ORDER BY state, first_name  		-- 主次关键词
ORDER BY 1, 2  						-- 可填列序,但应尽量避免
ORDER BY first_name ASC  			-- 升序排列(默认)
ORDER BY first_name DESC  			-- 降序排列,MySQL以外数据库对此支持不好
ORDER BY state DESC, first_name ASC	-- 组合补充:order by的执行顺序在select之后,故可以对新列别名进行排序
UNION(查询结果相加)
应用举例:找出工作岗位是SALESMAN和MANAGER的员工
select ename,job from emp where job='MANAGER'
union
select ename,job from emp where job='SALESMAN';LIMIT(限制)【MySQL特有】
注意:mysql中特有的,其他数据库没有,不通用。Oracle中有一个相同的机制叫rownum
用途:最大的用途就是分页查询,例如百度搜索每页显示10条数据
语法:limit [startIndex=0,] length,startIndex表示起始位置,length表示取几个
LIMIT 10  							-- 仅显示前10条
LIMIT 6, 3  						-- 跳过前6条/从序列6开始,显示后3条链接到当前文件 0
没有文件链接到当前文件