1、-- 多表连接
-- 1)内连接
-- 2)外连接
-- 3)自连接
-- 笛卡尔集(了解)-- 开发中,需要避免笛卡尔集
-- 如果要避免的话,我们需要包含一个有效连接条件的 where 子句。
-- 内连接-- 两个表(连接)中某一数据项相等的连接叫内连接。也叫等值连接。
eg:where tb_stu.clazz_id = tb_clazz.id
-- 内连接的运算顺序
-- 1)参与的数据表(或连接)中的每列与其它数据表(或连接)的列匹配,会形成一个临时表。
-- 2)将满足数据项相等的记录从临时数据表中选择出来。
-- 内连接的标准写法(了解)
-- inner join 就是相当于一个逗号 ,on后面写条件
select * from scott.dept d inner join scott.emp e
on d.deptno = e.deptno
and e.ename = 'SMITH'; -- 20
-- 外连接(非等值连接)
-- 用来查询一张表在另一张中没有关联数据的信息。
-- 外连接的三种方式
-- 1)左外连接 left outer join(重点)
-- 2)右外连接 right outer join
-- 2)全外连接 full outer join
select * from scott.emp; -- 13
select * from scott.dept; -- 7
-- 等值连接:两张表中都有的数据
select * from scott.dept d, scott.emp e
where d.deptno = e.deptno;
-- 左外连接
-- 技巧:如果是左外,就在右边加 + 号。
-- 左边的表会展示出所有的数据,右边表没有对应的数据则显示 null。
select * from scott.dept d, scott.emp e
where d.deptno = e.deptno(+);
-- 左外的标准写法
-- 书写的时候,需要注意:where 需要改为 on
select * from scott.dept d left outer join scott.emp e
on d.deptno = e.deptno;
-- 右外连接
select * from scott.dept d, scott.emp e
where d.deptno(+) = e.deptno;
select * from scott.dept d right outer join scott.emp e
on d.deptno = e.deptno;
-- 全外连接
select * from scott.dept d full outer join scott.emp e
on d.deptno = e.deptno;
-- 自连接(重点)
-- 在开发中使用比较广泛
-- 使用自连接的时候,相当于复制了一个镜像对象出来,并可以当做另外一张表来处理。
-- 使用了自连接可以把一张表当做多张表来使用,获取一些比较特殊的数据。
-- 使用技巧:可以考虑把它当做外键来玩。
select * from scott.emp;
-- 一个普通员工有自己的经理,经理也是一个员工,经理也有自己的经理
-- 查询 SMITH 的员工编号,名称,上级经理的编号,上级经理的名称
-- 创建一个临时表,数据来自 scott.emp
create table tb_temp as select * from scott.emp;
-- 关键厘清对象之间的关系
select e1.empno, e1.ename, e1.mgr, e2.ename
from scott.emp e1, tb_temp e2
where e1.mgr = e2.empno
and e1.ename = 'SMITH';
2、-- 组函数
-- 1)COUNT() 统计行数
-- 2)AVG() 平均值
-- 3)SUM() 求和
-- 4)MAX() 最大值
-- 5)MIN() 最小值
-- count() 函数
select count(*) from scott.emp;
-- sum() 函数
select sum(sal) from scott.emp;
-- avg() 函数
-- 平均值 = 总数 / 人数
select sum(sal)/count(ename) from scott.emp;
select avg(sal) from scott.emp;
-- max() 函数
select max(sal) from scott.emp;
-- min() 函数
select min(sal) from scott.emp;
select avg(sal), max(sal), min(sal) from scott.emp;
-- 查询的时候,注意结果的行数,如果不对称的话,则会报错
-- select ename, sum(sal) from scott.emp;
3、-- 分组查询
-- 使用 group by 语句。
-- 如果不想报错的话,需要将 select 后面列表中的字段添加到 group by 子句中即可。
-- 其实很简单,就是以 deptno 作为一个参照物,根据参照物定义出条件对象。
eg: select deptno, sum(sal) from scott.emp group by deptno;
4、 having 关键字过滤
--如果想在分组后,还需要进行条件过滤
-- 可以使用 having 关键字,追加条件
select deptno, sum(sal)
from scott.emp
group by deptno
having sum(sal) > 10000;
5、-- 常见的关键字使用顺序:
-- select > from > where > group by > having > order by
6、-- 子查询(重点)
-- 简单理解,在查询语句中,还有一个查询语句。
-- 子查询会在主查询之前先执行一次,将得到的结果当做是主查询的条件使用。
-- 子查询也叫内部查询。
-- 查询比 ALLEN 工资高的人
-- 1)先获取 ALLEN 的工资
select sal from scott.emp where ename = 'ALLEN'; -- 2600
-- 2)查找比 ALLEN 工资高的员工
select * from scott.emp where sal > 2600;
-- 使用子查询方式优化,一步搞定
select * from scott.emp where sal >
(select sal from scott.emp where ename = 'ALLEN');
-- 子查询中常用的几种运算方式:in、any、all
-- in:与列表中的任一值相等。就是一个 = 号
-- any:与子查询中返回的每一个值进行比较。
-- > any 大于最小的
-- < any 小于最大的
-- all:与子查询中返回的所有值进行比较。
-- > all 大于最大的
-- < all 小于最小的
-- in 包含:将所有部门中工资最少的找出来
select * from scott.emp where sal in
(select min(sal) from scott.emp group by deptno);
-- any
-- 大于最小的
select * from scott.emp where sal > any
(select min(sal) from scott.emp group by deptno);
-- 小于最大的
-- 是从分组的结果中,找到最大的值作为条件
-- 10 1300, 20 1100, 30 950
-- 此处最大值为 1300,查出来的值应该都要小于 1300
select * from scott.emp where sal < any
(select min(sal) from scott.emp group by deptno);
-- all
-- 大于 1300
select * from scott.emp where sal > all
(select min(sal) from scott.emp group by deptno);
-- 小于 950
select * from scott.emp where sal < all
(select min(sal) from scott.emp group by deptno);
7、--RowNum 和 RowId(了解)
-- 只有在 Oracle 数据库中才有。
-- RowNum
-- 伪列,主要是从 结果集 中产生出来的一个 序列。
-- 下标值,默认是从 1 开始的。
-- 只是临时生成出来使用的,不能保存的。
select rownum, deptno, dname, loc from scott.dept;
-- 查询第一条数据
select rownum, deptno, dname, loc
from scott.dept
where rownum > 0;
-- RowId
-- 它是一串随机生成字符串,固定且唯一的,就跟主键是一样的。
-- 当生成后,会存储到数据库中,相当于你存到内存中的内存地址一样。
-- 只有删掉对应的数据之后,它才会被删掉。
-- 我们通过 rowid 也可以查询数据,而且是最快的一种方式。
select rowid, deptno, dname, loc from scott.dept;
-- AAARE6AAEAAAACDAAA
select deptno, dname, loc
from scott.dept
where rowid = 'AAARE6AAEAAAACDAAA';
8、--常用函数
-- dual 是 orcle 提供的一个虚表
SELECT LENGTH('hello') FROM dual;
-- lower:把大写转小写,主要是将表中的数据进行转换小写,再去做比较。
eg: select lower('HELLOWORLD') from dual;
-- upper:把小写转大写
eg: select upper('helloworld') from dual;
--INITCAP:使串中的所有单词的首字母变为大写
eg: select INITCAP('sql course') from dual;
--CONCAT:连接两个字符串;
eg: select concat('Hello','World') from dual;
--取子字符串,从 start 开始,取 count 个
select substr('HelloWorld',1,3) from dual;
--取子字符串,从4开始取到末尾
select substr('HelloWorld',4) from dual;
--LENGTH:返回字符串的长度;
select length('HelloWorld') from dual;
--INSTR(string,char):在一个字符串中搜索指定的字符,返回发现指定的字符的位置,从1开始;
select INSTR('HelloWorld','l') from dual;
--TRIM:删除首尾的空字符串
select trim(' HelloWorld ') from dual;
select length(' HelloWorld ') from dual;
select length(trim(' HelloWorld ')) from dual;
--REPLACE('string','s1','s2')
--string 希望被替换的字符或变量
--s1 需要被替换的字符串 s2 替换的字符串
select REPLACE('HelloWorld','ll','FF') from dual;
--数值函数 四舍五入
select Round(45.926,2) from dual;
--截断
select TRUNC(45.926,2) from dual;
--取模
select MOD(1600,300) from dual;
-- 查询系统时间
SELECT SYSDATE FROM dual;
--日期函数
create table tb_test(
currdate date
);
insert into tb_test(currdate) values(sysdate); --插入当前日期
······
9、-- 集合运算
-- union
-- 主要是从两个查询中返回消除重复后的数据(类似于并集)
-- 效果类似于 distinct
eg:select deptno from scott.emp
union
select deptno from scott.dept;
-- union all
-- 主要是从两个查询中返回所有的数据
-- intersect
-- 主要是从两个查询中返回都会出现的数据(类似于交集)
select deptno from scott.emp
intersect
select deptno from scott.dept;
-- minus
-- 用来判断存在第一张表,而不存在第二张表中的数据(类似于差)
select deptno from scott.dept
minus
select deptno from scott.emp;