Oracle 入门到精通系列【 第 2章】

本文深入介绍了Oracle SQL的各种查询技巧,包括单表查询的简单条件、范围、排序、去重和聚合统计,连接查询的内连接、外连接,子查询的应用,分页查询的实现,以及单行函数、行列转换和集合运算的使用。内容详实,适合SQL初学者和进阶学习。
摘要由CSDN通过智能技术生成
  • 🚌一个人可以走的很快,一群人可以走的很远🇨🇳
  • 🎉点赞评论收藏 ➕关注== 养成习惯(一键四连)📝
  • 🎉欢迎关注💗一起学习👍一起讨论⭐️一起进步📝
  • 🙏作者水平有限,欢迎各位大佬指点,相互学习进步!😆

目录

一、单表查询

(一)简单条件查询

1.精确查询

2.模糊查询

3. and 运算符

4. or 运算符

5. and 与 or 运算符混合使用

6. 范围查询

7. 空值查询

(二)去掉重复记录

(三)排序查询

1.升序排序

2.降序排序

(四)基于伪列的查询

1、ROWID

2、ROWNUM

(五)聚合统计

1. 聚合函数

2. 分组聚合 Group by

3. 分组后条件查询 having

二、连接查询

(一)多表内连接查询

(二)左外连接查询

(三)右外连接查询

三、子查询

(一)where 子句中的子查询

(二)from 子句中的子查询

四、分页查询

(一)简单分页

(二)基于排序的分页

五、单行函数

(一)字符函数

常用字符函数讲解:

(二)数值函数

常用数值函数讲解:

(三)日期函数

常用日期函数讲解:

(四)转换函数

常用转换函数讲解:

(五)其它函数

(六)、case when

六、行列转换

(1)创建表格、插入测试数据

(2)查询每个人的每个科目分数

八、集合运算

(一)什么是集合运算

(二)并集运算

(三)交集运算

(四)差集运算


一、单表查询

(一)简单条件查询

1.精确查询

需求:查询员工号为7369的员工

select * from EMP where empno='7369';

查询结果:

2.模糊查询

需求:查询员工名包含“S”的业主记录

查询语句:

select * from EMP where ename like '%S%';

查询结果:

3. and 运算符

需求:查询员工名包含“S”并且工作包含“C”的记录

select * from EMP where ename like '%S%' and job like '%C%';

查询结果:

4. or 运算符

需求:查询员工名包含“S”或者工作包含“C”的记录

查询语句:

select * from EMP where ename like '%S%' or job like '%C%';

查询结果:

5. and 与 or 运算符混合使用

需求:查询员工名包含“S”或者工作包含“C”的记录,并且员工号为7369的员工记录。

查询语句:

select * from EMP where (ename like '%S%' or job like '%C%') and empno='7369';

查询结果:

因为 and 的优先级比 or 大,所以我们需要用 ( ) 来改变优先级。

6. 范围查询

需求:查询员工薪水大于1000,并且小于3000的记录我们可以用>= 和<=来实现

查询语句:

select * from emp where sal <=3000 and sal >=1000;

我们也可以用 between .. and ..来实现

select * from emp where sal between 1000 and 3000;

查询结果:

7. 空值查询

需求:查询 emp 表中 comm 为空的记录

查询语句:

select * from emp where comm is null;

查询结果:

需求:查询 emp 表中 comm 不为空的记录

查询语句:

select * from emp where comm is not null;

查询结果:

(二)去掉重复记录

需求:查询emp 表中的 deptno,不重复显示

查询语句:

select distinct deptno from emp;

查询结果:

(三)排序查询

1.升序排序

需求:对 emp 表按薪水进行升序排序

查询语句:

select * from emp order by sal asc;

查询结果:

2.降序排序

select * from emp order by sal desc;

(四)基于伪列的查询

在 Oracle 的表的使用过程中,实际表中还有一些附加的列,称为伪列。伪列就像表中的列一样,但是在表中并不存储。伪列只能查询,不能进行增删改操作。

接下来学习两个伪列:ROWID 和 ROWNUM。

1、ROWID

表中的每一行在数据文件中都有一个物理地址,ROWID 伪列返回的就是该行的物理地址。使用 ROWID 可以快速的定位表中的某一行。ROWID 值可以唯一的标识表中的一行。由于 ROWID 返回的是该行的物理地址,因此使用 ROWID 可以显示行是如何存储的。

查询语句:

select rowID,e.* from emp e;

查询结果:

我们可以通过指定 ROWID 来查询记录

select rowID,e.* from emp e where ROWID='AAASNYAAGAAAACWAAB';

2、ROWNUM

在查询的结果集中,ROWNUM 为结果集中每一行标识一个行号,第一行返回 1,第二行返回 2,以此类推。通过 ROWNUM 伪列可以限制查询结果集中返回的行数。

select rownum,e.* from emp e;

我们的分页查询需要用到此伪列,在本章第四小节详细讲解。

(五)聚合统计

ORACLE 的聚合统计是通过分组函数来实现的,与 MYSQL 一致。

1. 聚合函数

(1)求和 sum

需求:统计所有员工的薪水之和

select sum(sal) from emp;

(2)求平均 avg

需求:统计所有员工的平均薪水

select avg(sal) from emp;

(3)求最大值 max

需求:统计所有员工的最高薪水

select max(sal) from emp;

(4)求最小值 min

需求:统计所有员工的最低薪水

select min(sal) from emp;

(5)统计记录个数 count

需求:统计所有用工数

select count(1) from emp;

select count(*) from emp;

2. 分组聚合 Group by

需求:按部门分组统计薪水总和

select deptno,sum(sal) from emp group by deptno;

3. 分组后条件查询 having

需求:按部门分组统计薪水总和,并且部门薪水总和大于1万的

select deptno,sum(sal) as sumSal from emp group by deptno having sum(sal)>10000;

二、连接查询

(一)多表内连接查询

(1)需求:查询员工部门名称

select * from emp e,dept d where e.deptno = d.deptno;

(2) 查询各部门的平均薪水及部门编号,部门名称。

SELECT AVG(SAL),DNAME,EMP.DEPTNO FROM EMP,DEPT where EMP.DEPTNO = DEPT.DEPTNO GROUP BY DNAME,EMP.DEPTNO;

(二)左外连接查询

查询员工姓名及领导者姓名

select a.ename AS 员工姓名 ,b.ename AS 领导姓名 from emp a LEFT JOIN emp b on a.mgr = b.empno;

其他例子:

用户表、商品表:根据用户id查询用户所属商品

商品表、图片表:根据商品ID查询商品所属图片

(三)右外连接查询

通上类似,right join

三、子查询

(一)where 子句中的子查询

1. 单行子查询

  • 只返回一条记录
  • 单行操作符

1、查询薪水的最高值

select sal from emp where sal = (select max(sal) from emp);

2、 查询‘SMITH’的领导姓名

SELECT ENAME FROM EMP WHERE EMPNO = (SELECT MGR FROM EMP WHERE ENAME = 'SMITH');

3、 查询部门名称是‘SALES’的员工信息

SELECT * FROM EMP WHERE DEPTNO = (SELECT DEPTNO FROM DEPT WHERE DNAME = 'SALES');

2. 多行子查询

  1. 返回了多条记录
  2. 多行操作符

in 运算符

1、 查询各部门中最高薪水的员工编号,姓名…

select empno , ename,DEPTNO from emp WHERE SAL in (select MAX(SAL) from EMP GROUP BY DEPTNO);

2、 查询各部门最高薪水的员工信息(有坑)(薪水和部门编号都需要匹配)

select * from EMP where (deptno,SAL) in (select deptno,MAX(sal) from emp GROUP BY DEPTNO);

3、 查询各部门最高薪水的员工信息

select * from EMP where (deptno,SAL) in (select deptno,MAX(sal) from emp GROUP BY DEPTNO);

(二)from 子句中的子查询

select * from ( select * from )

select * from ( select * from emp )

四、分页查询

需要准备t_user进行批量插入数据,我们这里循环插入一些数据,使用前面讲解的JDBC进行插入数据


    @Test
    public void add(){
        UserDao userDao = new UserDao();
        for(long i=409;i<550;i++){
            User user = new User();
            user.setId(i);
            user.setUserName("张三"+i);
            user.setPassword("123456"+i);
            userDao.add(user);
        }

    }

(一)简单分页

需求:分页用户表t_user,每页 10 条记录

分析:我们在 ORACLE 进行分页查询,需要用到伪列 ROWNUM 和嵌套查询我们首先显示前 10 条记录,语句如下:

select rownum,tt.* from T_USER tt where rownum<=10;

显示结果如下:

那么我们显示第 11 条到第 20 条的记录呢?编写语句:

select rownum,t.* from T_USER t where rownum>10 and rownum<=20;

查询结果:

嗯?怎么没有结果?

这是因为 rownum 是在查询语句扫描每条记录时产生的,所以不能使用“大于” 符号,只能使用“小于”或“小于等于” ,只用“等于”也不行。

那怎么办呢?我们可以使用子查询来实现

select * from (select rownum r,t.* from T_USER t where rownum<=20) where r>10;

查询结果如下:

注:rownum是虚拟列,是得出结果后,再进行计算的。所以,只能是小于的,无法大于。

(二)基于排序的分页

需求:分页用户表t_user,每页 10 条记录,按ID降序排序。

第一步:先做ID降序排序,查看rownum

select rownum,t.* from T_USER t where t.id<=30 order by id desc;

第二步:根据查询出来的数据分页

第一页数据:select * from (select rownum r,t.* from T_USER t where t.id<=30 and rownum<=30 order by id desc) m where m.r>=21 ;

第二页数据:select * from (select rownum r,t.* from T_USER t where t.id<=20 and rownum<=30 order by id desc) m where m.r>=11 ;

分析:这时候分页和上面的分页逻辑就反了,所以不适合。因为rownum是查询结果的一个值!

第三步:使用三层嵌套分页

先排序好数据,生成固定的rownum,之后基于这个结果再去做查询,生成外层的一个rownum,基于这个rownum再去做正序分页。

第一页数据:select * from (select rownum r,t.* from (select t.* from T_USER t where t.id<=30 order by id desc) t where rownum<=10) where r>0;

第二页数据:select * from (select rownum r,t.* from (select t.* from T_USER t where t.id<=30 order by id desc) t where rownum<=20) where r>10;

五、单行函数

(一)字符函数

常用字符函数讲解:

(1)求字符串长度 LENGTH

select length('ABCD') from dual;

(2)求字符串的子串 SUBSTR

select substr('ABCD',2,2) from dual;

(3)字符串拼接 CONCAT

select concat('ABC','D') from dual;

select 'ABC'||'D' from dual;

(二)数值函数

常用数值函数讲解:

(1)四舍五入函数 ROUND

select round(100.567) from dual

select round(100.567,2) from dual

(2)截取函数 TRUNC

select trunc(100.567) from dual

select trunc(100.567,2) from dual

(3)取模 MOD

select mod(10,3) from dual

(三)日期函数

我们用 sysdate 这个系统变量来获取当前日期和时间

select sysdate from dual

常用日期函数讲解:

(1)加月函数 ADD_MONTHS :在当前日期基础上加指定的月

select add_months(sysdate,2) from dual

(2)求所在月最后一天 LAST_DAY

select last_day(sysdate) from dual

(3)日期截取 TRUNC

select TRUNC(sysdate) from dual

select TRUNC(sysdate,'yyyy') from dual

select TRUNC(sysdate,'mm') from dual

(四)转换函数

常用转换函数讲解:

(1)数字转字符串 TO_CHAR

select TO_CHAR(1024) from dual

(2)日期转字符串 TO_CHAR

select TO_CHAR(sysdate,'yyyy-mm-dd') from dual

select TO_CHAR(sysdate,'yyyy-mm-dd hh:mi:ss') from dual

(3)字符串转日期 TO_DATE

select TO_DATE('2017-01-01','yyyy-mm-dd') from dual

(4)字符串转数字 TO_NUMBER

select to_number('100') from dual

(五)其它函数

(1)空值处理函数 NVL

select NVL(NULL,0) from dual

(2)空值处理函数 NVL2

用法:

NVL2(检测的值,如果不为 null 的值,如果为 null 的值);

(3)条件取值 decode

语法:

decode(条件,值 1,翻译值 1,值 2,翻译值 2,...值 n,翻译值 n,缺省值)

【功能】根据条件返回相应值

(4)case when

(六)、case when

case when:条件判断语句
	(1) 相当于其它语言中的 if else
	(2) 部分情况下,等同于 decode()
case when 表达式用两种形式
    -- 简单 case 函数,要求:when 对象的类型 和 case 对象的类型一致
    -- 此时等同于 decode(sex, '1', '男', '2', '女')
    case sex
      when '1' then '男'
      when '2' then '女'
    else
      '其它'
    end;
   -- case 表达式
   case
     when sex = '1' then '男'
     when sex = '2' then '女'
   else
     '其它'
   end;
注意:when 的执行顺序,当 '第一个' when 满足条件时,便结束查询
	   (不会继续判断其它的 when 条件) 
建议:当 case when 和 decode 等价,且判断语句不超过 10 行时,
        使用 decode(语法简洁)
with t_score as (
  select 90 score, '瑶瑶' name from dual union all
  select 80 score, '倩倩' name from dual union all
  select 70 score, '优优' name from dual 
)
select t.name,
       t.score,
       (case
         when t.score >= 90 then
          '优秀'
         when t.score >= 80 then
          '良好'
         when t.score >= 60 then
          '及格'
         else
          '不及格'
       end) 评分
  from t_score t;

六、行列转换

(1)创建表格、插入测试数据

create table kecheng
(
  id     NUMBER,
  name   VARCHAR2(20),
  course VARCHAR2(20),
  score  NUMBER
);
insert into kecheng (id, name, course, score)
values (1, '张三', '语文', 67);
insert into kecheng (id, name, course, score)
values (1, '张三', '数学', 76);
insert into kecheng (id, name, course, score)
values (1, '张三', '英语', 43);
insert into kecheng (id, name, course, score)
values (1, '张三', '历史', 56);
insert into kecheng (id, name, course, score)
values (1, '张三', '化学', 11);
insert into kecheng (id, name, course, score)
values (2, '李四', '语文', 54);
insert into kecheng (id, name, course, score)
values (2, '李四', '数学', 81);
insert into kecheng (id, name, course, score)
values (2, '李四', '英语', 64);
insert into kecheng (id, name, course, score)
values (2, '李四', '历史', 93);
insert into kecheng (id, name, course, score)
values (2, '李四', '化学', 27);
insert into kecheng (id, name, course, score)
values (3, '王五', '语文', 24);
insert into kecheng (id, name, course, score)
values (3, '王五', '数学', 25);
insert into kecheng (id, name, course, score)
values (3, '王五', '英语', 8);
insert into kecheng (id, name, course, score)
values (3, '王五', '历史', 45);
insert into kecheng (id, name, course, score)
values (3, '王五', '化学', 1);
commit;

(2)查询每个人的每个科目分数

SELECT ID,NAME,
MAX(CASE WHEN course='语文' THEN score ELSE 0 END) 语文,
MAX(CASE WHEN course='数学' THEN score ELSE 0 END) 数学,
MAX(CASE WHEN course='英语' THEN score ELSE 0 END) 英语,
MAX(CASE WHEN course='历史' THEN score ELSE 0 END) 历史,
MAX(CASE WHEN course='化学' THEN score ELSE 0 END) 化学
FROM kecheng
GROUP BY ID ,NAME;

八、集合运算

(一)什么是集合运算

集合运算,集合运算就是将两个或者多个结果集组合成为一个结果集。集合运算包括:

··UNION ALL(并集),返回各个查询的所有记录,包括重复记录。

··UNION(并集),返回各个查询的所有记录,不包括重复记录。

··INTERSECT(交集),返回两个查询共有的记录。

··MINUS(差集),返回第一个查询检索出的记录减去第二个查询检索出的记录之

后剩余的记录。

(二)并集运算

UNION ALL 不去掉重复记录

select * from t_user where id<=7 union all select * from t_user where id>=5;

UNION 去掉重复记录

select * from t_user where id<=7 union select * from t_user where id>=5;

(三)交集运算

select * from t_user where id<=7 intersect select * from t_user where id>=5; 

(四)差集运算

select * from t_user where id<=7 minus select * from t_user where id>=5;

 

 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑石课堂

请给我打钱!!!谢谢,不客气!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值