DQL数据查询语言
简单查询
-
语法
select 想要查询的字段 from 表名; -
注释
--这是单行注释 /*这是多行注释 这是多行注释 */
-
别名
可以给表起别名,也可以给列(字段)起别名。
关键词:as
注意:在给列(字段)起别名时,可以使用as关键字也可以不用,但是给表起别名不可以使用as关键字。select * from emp e;
select e.empno as 员工编号 from emp e;
-
带条件查询
1、 关键字:whereselect * from emp where deptno = 10;
2、结合条件查询可使用的关键字
in、not in
条件连接符:and、or、between and
条件表达式:>、<、=、>=、<=、!=、<>
is null、is not null查询所有工种不是MANAGER和CLERK,且工资大于或等于2000的员工的详细信息; SELECT * FROM emp e WHERE e.job NOT IN ('MANAGER','CLERK') AND e.sal >= 2000;
查询没有奖金或奖金低于100的员工信息; SELECT * FROM emp e WHERE e.comm < 100 OR e.comm IS NULL;
-
模糊查询
关键字:like语法格式:select 列名 from 表名 where 字段名(列名) like '匹配格式'
占位符:_ 该占位符出现的地方有且只能有一个字符 % 该占位符出现的地方可以有0个或多个字符
注意:如果要匹配的字符串中含有特殊字符(_%),就需要在特殊字符前加上转义字符将该特殊字符转换为普通字符去匹配,使用转移字符需要手动去定义,定义关键字是 escape。
SELECT * FROM emp WHERE ename LIKE '%a_%' ESCAPE 'a'; SELECT * FROM emp WHERE ename LIKE '%/_%' ESCAPE '/';
排序分组
-
分组
1、关键字:group by语法:select 列名,列名,...,列名 from 表名 where 条件 group by 分组列 group by 后面跟多个列时,只有当多个列的值同时相等时,它才会分为同一个组。
注意:在oracle中必须在 select 子句中使用 group by 子句中的所有列,或者使用聚合函数(函数中详细描述)对其进行计算,否则就会报错;但在Mysql中,不会报错。
2、分组拼接
wm_concat(列)
listagg(列,‘分隔符’)WITHIN GROUP(ORDER BY 列)二者区别:二者都是实现分组拼接,但是wm_concat在分组拼接中默认用逗号隔开;listagg可以手动修改分隔符,并且可以在组内按照某一列进行排序。 1、求部门的员工数以及所有的人员名字(用wm_concat) SELECT DEPTNO,COUNT(*),WM_CONCAT(ENAME) FROM EMP GROUP BY DEPTNO; 2、求部门的员工数以及所有的人员名字(用listagg修改分隔符) SELECT DEPTNO,COUNT(*),listagg(ename,'-')WITHIN GROUP(ORDER BY ename) FROM EMP GROUP BY DEPTNO;
-
排序
关键字:order by语法: select 列名,列名,..,列名 from 表名 where 条件表达式 order by 排序列的列名 asc|desc; 注意: 1、order by 后面可以跟多个排序列,含义为:按照第一个排序列进行排序,如果第一个排序列的值相等时,才会按照第二个排序列进行排序。 2、order by 后面除了可以跟表中的列名之外,还可以跟select和from之间的序号。 3、NULLS LAST 把空值放在最后;NULLS FIRST 把空值放在第一位。
-
having
select 列名 from 表名 where 条件 group by 分组列 having 条件 having与where的区别: 二者都是用于筛选数据,但是where子句是在对数据进行分组之前过滤数据的,用于在查询返回结果集之前过滤;having子句则是在对数据进行分组之后过滤数据的。having在group by 子句后面使用,用于限制group by 子句返回的结果集。
重点:既然写到了where和having,就说一下sql语句的执行顺序:from->where->group by .... having->聚合函数->select语句->order by。
集合、联合查询
-
三大集合操作符
1、返回两个查询的公共行,也就是交集—intersect
2、返回两个查询结果的并集,不包含重复值—union
注意:union all 要比 union的执行效率高,因为union会先合并再排序,最后去重
3、返回两个查询结果的并集,包含重复值—union allSELECT ename,sal FROM emp UNION SELECT '总计',SUM(sal) FROM emp; 输出结果见下图
4、从第一个查询结果减去第二个查询结果,也就是差集—minus
-- 查询工资大于1000的员工 SELECT * FROM EMP WHERE SAL > 1000 MINUS -- 查询工资小于3000的员工 SELECT * FROM EMP WHERE SAL < 3000; 执行输出结果为 查询出工资大于等于3000的员工信息
-
联合查询
1、交叉连接(笛卡尔连接)定义:返回结果的行数等于两个表行数的乘积 语法:select 列名,列名,... from 表1 cross join 表2; 注意:如果两个表数据量过多时不要轻易使用笛卡尔连接
2、内连接
定义:把表中符合条件的数据连接为一条数据,如果哪个表中存在不符合连接条件的数据,那么这些数据就会过滤掉不显示 语法-标准写法:select 列名,列名,... from 表1 [inner] join 表2 on 连接条件 语法-另一种写法:select 列名,列名,... from 表1,表2 where 连接条件
where和on的区别:where是先连接后筛选,on是先筛选后连接
3、自连接定义:自连接是一个特殊的内连接,自己和自己连接 语法:select 列名,列名,... from 表 别名 inner join 表 别名 on 连接条件 举例:-- 查询所有员工信息 以及 他们的领导信息(emp表) SELECT * FROM EMP E1 INNER JOIN EMP E2 ON E1.MGR = E2.EMPNO;
4、不等连接
定义:连接条件是不等条件,即大于、小于、不等于 举例: -- 查询所有员工信息以及他们的工资等级 SELECT * FROM EMP E INNER JOIN SALGRADE S ON E.SAL BETWEEN S.LOSAL AND S.HISAL; 结果见下图
5、外连接
外连接又分为全连接、左外连接、右外连接
全连接定义:会查出两个表中的所有数据,如果两表数据符合条件,就同内连接一样,如果第一张表的数据在第二张表中没有数据则显示空,第二张同理 语法:select 列名,列名,列名,.... from 表1 full [outer] join 表2 on 连接条件 ****************************************************************************************************************** 左外连接定义:查出左表(left outer join关键字前面的表)的所有数据,根据连接条件去右表中找对应的数据,如果找到变显示出来,如果找不到就显示空 语法:select 列名,列名,列名,.... from 表1 left [outer] join 表2 on 连接条件 ****************************************************************************************************************** 右外连接同理,语法为:select 列名,列名,列名,.... from 表1 right [outer] join 表2 on 连接条件
左右外连接的另一种写法为:用(+)表示的左连接或者右连接,(+) 写在谁后面 谁就是次表
6、自然连接定义:自然连接是在两张表中寻找那些数据类型和列名都相同的字段,然后自动地将他们连接起来,并返回所有符合条件按的结果。 语法:select 列名,列名,列名,.... from 表1 natural join 表2 注意:当两张中有多个字段名字、类型都相同的时候 就不能使用natural ,这个时候就用内连接 using 指定 SELECT * FROM EMP JOIN DEPT USING(DEPTNO);
子查询
子查询有好几类,正所谓大道至简,无论是from后面的子查询、where后面的子查询、having后面的子查询、select from之间的子查询还是exist后面的子查询,都可以理解所select子句中嵌套一个或多个select子句,不过是位置不同实现逻辑不同罢了。
1、from后面的子查询可以这么理解,普通查询语句 select * from 表 实现查询一个表中的所有记录,那么在from后面再加一个select子句,这个子句查询出的结果就理解为一个表。
2、select from 之间的子查询就可以这么理解,select 列名,列名,… from 表 这个语句用来查询某个表中对应几个字段的数据,字段即列名,列名是一个单行单列的存在,所以select 和 from 之间子查询的结果只能是单行单列。
3、where后面的子查询可以这么理解,where后面都是加的判断条件,进行条件判断时就需要用到我们的条件判断符,判断符两端无论是某一字段也好还是一个子查询也好,二者必须可以进行逻辑判断,举个栗子:selelct * from emp where sal > (10,20,30) 可以执行吗?结果很显然会报错,因为当拿到一条员工信息中的工资时无法和后面的数据进行比较,没有办法进行逻辑上的判断,如果想要实现一条数据和多条数据进行逻辑判断需要用到关键字all、any,关于这两个关键字下面做具体的介绍和举例。
4、having后面的子查询同where后面的子查询处介绍,二者都是筛选的关键字,区别就是在于having对于分组后的数据进行筛选。
5、exists后面的子查询分为相关性子查询和非相关性子查询,如何理解呢?select * from 表1 where exists(select * from 表2 where 判断条件) 这条语句,如果exists后的子查询中的判断条件出现表1中的字段,即无法单独执行exists后面的子查询时便是相关性子查询,非相关性子查询正好相反。
此处介绍any和all,any即任意,all即所有,结合下面介绍理清逻辑即可
all、any:后面都跟一个集合或者子查询,区别在于
>all:表示大于集合中最大的元素 >all(1,2,3,4,5) 等价于 >5
<all:表示小于集合中最小的元素 <all(1,2,3,4,5) 等价于 <1
>any:表示大于集合中最小的元素 >any(1,2,3,4,5) 等价于 >1
<any:表示小于集合中最大的元素 <any(1,2,3,4,5) 等价于 <5
分页
rownum是Oracle数据库内置列,任何表都可以使用,作用是显示行号。
分页SQL介绍可以结合分析函数一起理解,可以转到我的另一篇博客中查看