Oracle学习笔记第七天
查询这功能是经常使用的部分,可能我这边暂时学到的只有这么多,或许存在遗漏,如果有,以后补上。
先来个完整的,
SELECT [ALL|DISTINCT] TOP n [PERCENT] WITH THIS select_list
[INTO [new table name]]
[FROM {table_name | view_name}[(optimizer_hints)]
[,{table_name2 | view_name2}[optimizer_hints]
[...,table_name16 | view_name16][optimizer hints]
]
]
[WHERE clause]
[GROUP BY clause]
[HAVING clause]
[ORDER BY clause]
[COMPUTE clause]
[FOR BROWSE]
别看这这么多,拆分介绍完,你就会发现,感觉还行,但是真正用的时候会很蛋疼。熟练就好了。
这玩意一次介绍说不清,分开介绍。
-
简单查询
只有select 和 from 的查询时简单查询。也是基本查询,所有的查询都必须包含这两个子句。
select * from teachers; -- 查询老师表里所有的数据。
-
使用from子句指定表
[FROM {table_name | view_name}[(optimizer_hints)] [,{table_name2 | view_name2}[optimizer_hints] [...,table_name16 | view_name16][optimizer hints] ] ]
使用 from 可以查询行和列所在的表,指定表后,就可以通过表查询都所需要的行列值,注意这里没有where条件,所以查询出来的数据是整张表的数据。
table_name:表示表名,view_name:表示视图名,视图后面会介绍。
在查询其他角色对应的方案中的表时,需要指定该方案的名称,即在表名前加对应的角色名,比如我的teachers表建在pptt角色下,则查询为:
select * from pptt.teachers;
-
使用select 指定列
很多时候,我们查询的可能只是某张表里的某个或者某几个字段,并不需要查询出整张表的数据。
SELECT column_1 [name_1] [,... column_n name_n] FROM table_name_1 [tname_1] [, ... table_name_n,tname_n]
column_1,column_n:要读取的列名,可以为多个,也可以为一个。 name_1:有的时候看列名很难理解其中的意思,可以在后面加一个字符串代替这个列名,这个不会影响数据。 table_name_1:要读取的表名。 [tname_1]:和name_1功能类似,不过是替换表名。当表名过长的时候,通过替换可以使得SQL变得简洁。 选择列名的时候不用按照之前的顺序,但是显示的时候是按照你写的列名顺序排序的。 在选择列名的时候也可以对列名进行操作,包括一般的加(+)减(-)乘(*)除(/)
select (degree + 5) '学生成绩' from scores; -- 显示每个学生加5分后的成绩
-
distinct / all关键字
数据去重,比如说银行的交易记录,比如说你想从部门成员表中查询有哪些部门,一个部门可能有多个人,这是这个部门在显示的时候就是重复出现的,这时可以使用数据去重,使得相同的数据只存在一个。
select distinct department_id from employees;
all 则是查询所有数据,一般忽略不写。
-
where 子句
查询的时候我们可能只需要符合某些条件的数据,而不是所有的数据,这时就可以使用where条件,筛选数据。
-
条件表达式
可以使用类似 A = B,A < B,A != B,A<>B,A LIKE B,NOT<条件表达式>的语句。A、B可以是字段,也可以是数字,也可以是字符串。这里条件比较的是你想要的数据符合哪些规则。
like是匹配运算符,Oracle在匹配运算中支持通配符,“%”代表0个、1个或者多个任意字符,“_”代表一个任意字符。
not 用于对里面的结果取反。
select * from teacher where tname like '李%'; -- 查询所有的李老师。
-
连接运算符
and、or
当判断条件不止一个时可以使用and、或者or连接多个条件,至于功能不在细说。
-
null值
null这玩意,我不怎么喜欢,但是数据没有的值的情况下,就是null值。
判断数据是否为null时特定判断语法 is null 、 not is null;
select * from students where sbrithday is not null; -- 查询生日不为空的学生信息
-
-
order by 子句
用于对查询出来的数据进行排序。ASC是升序,DESC是倒序。
select * from scores order by sno ASC,degree DESC; -- 查询学生成绩,按照课程升序后按照成绩倒序。
-
group by 子句
按照查询的数据进行分类。用于在查询结果集中对记录进行分组,以汇总数据或者为整个分组显示单行的汇总信息。
比如说,我要查询每个部分有多少人,这样的话,我可以按照部分分组,然后统计每部门的人数。
select count(1) from emp group by deptno;
常用的统计函数
函数 描述 count 返回找到的记录数 min 返回一个数字列或是计算列的最小值 max 返回一个数字列或是计算列的最大值 sum 返回一个数字列或是计算列的总和 avg 返回一个数字列或是计算列的平均值 e.g 使用group by 子句对薪资记录进行分组,统计薪资的平均值,总和,以及最大值。
select job_id ,avg(salary),sum(salary),max(salary),count(job_id) from employees group by job_id;
注意:在使用group by 语句的时候,需要满足的条件: 1. 在 select 子句的后面只可以有两类表达式,统计函数和进行分组的列名; 2. 在select 子句中的列名必须是进行分组的列,除此之外添加其他的列名都是错误的,但是, group by 子句后面的列名可以不出现在select子句中; 3. 如果使用了 where 子句,那么所有参加分组计算的数据必须首先满足 where 子句指定的条件; 4. 在默认情况下,将按照 group by 子句指定的分组列升序排列,如果需要重新排序,可以使用 order by 子句指定新的排序顺序。
-
Having 子句
having 与 where 的功能类似,但是 where 只能用于条件判断,后面不能跟函数,having 后面可以供函数。
在 select 语句中,首先由 from 子句找到数据表,where 子句则接收 from 子句的输出的数据,而having 子句则接收来自 group by、where或者from子句的输入。
e.g:列出平均薪资大于10000的统计信息
select job_id,avg(salary),sum(salary),max(salary),count(*) from employees group by having avg(salary)>10000;
-
多表连接查询
-
简单连接
连接查询仅通过 select 子句和 from 子句来连接多个表,其查询的结果是一个通过笛卡尔积所生成表。,就是由一个表的每一行与另一个表的每一行的数据连接在一起生成的表,查询结果的行数是两个表的行数的乘积。
一般不用这样的,数据冗余,很多时候我们不需要这么多数据,一般会加上条件限制。即加上 where 子句,只有当第一张表和第二张表符合 where 里的条件时,才会显示。
有时候连接的表有相同的列,这时候就难以区分这列是哪个表的,这时候可以用表别名来区分。
有的时候,表名过长,也可以使用表别名来时SQL简洁。
注意:使用表别名后,所有的字段必须加上表别名,因为SQL解析器在解析 from 子句时会用表别名代替表名,如果没有加表别名,或者还是用表名,则会报错。
e.g:查询雇员信息,以及雇员所对应的部分信息,且只显示工作部门为Shipping的雇员信息
select em.employee_id,em.last_name,dep.department_name from employees em,departments dep where em.department_id = dep.department_id and dep.department_name = 'Shipping';
-
join连接
from join_table1 join_type join_table2 [on(join_condition)]
join_table1,join_table2:要连接的表 join_type:连接类型,常用有:内连接、自然连接、外连接和自连接。 [on(join_condition)]:连接的条件。
内连接:(关键字:inner join,inner 可以省略)
内连接就是使用join指定用于连接的两个表,使用ON指定连接表的连接条件,如果想进一步限制查询范围,则可以直接在后面添加where子句。
e.g:使用内连接查询雇员的信息,名称以及工作名称。
select em.employee_id,em.last_name,dep.department_name,j.job_title from employees em inner join jobs j on em.job_id = j.job_id inner join departments dep on em.department_id = dep.department_id where em.job_id = 'IT_PROG';
自然连接:(关键字:natural join)
在使用自然连接查询多个表时,Oracle会将第一张表的列与第二张表中具有相同名称的列进行连接,在自然连接中,用户不需要明确指定进行连接的列,系统会自动完成。
但是自然连接诶有一个限制,即连接的各个表之间必须具有相同名称的列,这个在实际中可能和应用的实际含义发生矛盾。
比如:雇员有家庭住址,,部门有所在地址,这两个连接就会放在一起,这样的连接时毫无意义的。所以自然连接一般使用的很少。
外连接:
外连接分为三种:左外连接(left outer join 或者 left join)、右外连接(right outer join 或者 right join)、全外连接(full outer join 或者 full join)
外连接与内连接的区别:外连接不只列出连接条件匹配的行,还列出左表(左外连接时)、右表(右外连接时)或者两个表(全外连接时)中所有符合搜索条件的数据行。
理解很简单,就比如说现在有两个集合,内连接就是找出两个集合的交集,左外连接就是找出左边集合的全部,同时左边集合与右边集合的交集部分会附带右边集合的数据,右外连接同理,全外连接就是左右两个集合的并集,左外连接和右外连接的交集部分会按照条件聚集在一起。
自连接:
自连接就是自己再次连接自己。
-
-
集合操作
集合操作就是讲两个或者多个SQL查询结果合并构成复合查询,以完成一些特殊的任务需求,集合操作主要有集合操作符实现,常用的集合操作符包括:
UNION(并运算)、UNION ALL、INTESECT(交运算)和MINUS(差运算)。
-
UNION
UNION 运算符可以将多个查询结果集相加,形成一个结果集,其结果等同于集合运算中的交运算,并消除其中重复的行形成一个合集。
e.g:查询以 C 或者以 S 开头的雇员,UNION 上 以 S 开头或者以 T 开头的雇员,这时返回的结果集有以C、S、T 开头的雇员。
select employee_id,last_name from employees where last_name like 'C%' or last_name like 'S%' union select employee_id,last_name from employees where last_name like 'S%' or last_name like 'T%'
-
UNION ALL
这个和 UNION 功能一致,但是这个不会去除重复行。
-
INTERSECT
INTERSECT操作符也用于对两个SQL语句所产生的结果集进行处理,不同之处是 UNION 基本上是一个 OR 运算,而 INTERSECT 则比较像 AND。即UNION 交集运算,而 INTERSECT 是并集运算。
e.g:查询以 C 或者以 S 开头的雇员,INTERSECT上 以 S 开头或者以 T 开头的雇员,这时返回的结果集只有 S 开头的雇员。
select employee_id,last_name from employees where last_name like 'C%' or last_name like 'S%' INTERSECT select employee_id,last_name from employees where last_name like 'S%' or last_name like 'T%'
-
MINUS
MINUS 集合运算可以找到两个给定的集合之间的差集,返回的是第一个查询中有的,但是第二个查询中没有的。
e.g:查询以 C 或者以 S 开头的雇员,MINUS上 以 S 开头或者以 T 开头的雇员,这时返回的结果集只有 C 开头的雇员。
select employee_id,last_name from employees where last_name like 'C%' or last_name like 'S%' MINUS select employee_id,last_name from employees where last_name like 'S%' or last_name like 'T%'
使用集合操作符的规则: 1. 在构成符合查询的各个查询中,各 select 语句指定的列必须在数量上和数据类型上相匹配; 2. 不允许在构成复合查询的各个查询中规定 order by 子句; 3. 不允许在BLOB、LONG 这样的大数据类型对象上使用集合操作符。
-
-
子查询
子查询是一个 select 语句,它可以在 select 、insert 、 update 或者 delete 语句中使用。
-
IN 关键字
使用IN 关键字可以将原表中特定列的值域子查询返回的结果集中的值进行比较,如果某行的特定列的值存在,则在select语句的查询结果中就包含这一行。
e.g:查询所有部门在某一地区(1700)的雇员信息。
select employee_id,last_name,department_id from employees where department_id in (select department_id from departments where location_id = 1700);
-
EXISTS 关键字
EXISTS关键字只注重子查询是否返回行,如果子查询返回一个或多个行,那么 EXISTS 便返回 true,否则 false。
由于 EXISTS 关键字的返回值取决于查询是否会返回行,而不取决于这些行的内容,因此对子查询来说,输出的列表无所谓,可以使用 * 代替。
-
比较运算符
包括:=、<>(不等于)、<、>、<=、>=。
-