用户对表或视图最常进行的操作就是检索数据,检索数据可以通过 select 语句来实现,该语句由多个子句组成,通过这些子句完成筛选、投影和连接等各种数据操作,最终得到想要的结果。
语法:
select { [ distinct | all ] columns | * }
[ into table_name ]
from { tables | views | other select }
[ where conditions]
[ group by columns ]
[ having conditions ]
[ order by columns ]
- select子句 :用于选择数据表、视图中的列
- into 子句:用于将原表的结构和数据插入新表中
- from 子句:用于指定数据来源,包括表,视图和其他select 语句。
- where 子句:用于检索的数据进行筛选
- group by 子句:用于检索结果进行分组显示
- having 子句:用于从使用group by子句分组后的查询结果中筛选数据行
- order by 子句:用来对结果集进行排序(包括升序和降序)
一、简单查询
只包含select 子句和 from 子句的查询就是简单查询,同时也是select语句的必选项。
select 子句用于选择想要在查询结果中显示的列,这些列可以用列名来表示,也可以使用星号(*)来表示。查询数据时,数据将按照select 子句后面指定的列名顺序来显示;如果使用星号,则表示查询所有的列,这时候按照表结构的自然顺序来显示。
1、检索所有的列
如果想要检索知道数据表的所有列,在select 子句后面加星号来实现。
语法: select * from table_name;
注意:a、检索数据表需要注意是否属于该模式,如果是模式内部检索数据,直接使用表名;
b、如果不在指定表所属的模式内部检索数据,不仅要查看当前模式是否具有查询的权限,而且还要在表名前面驾驶所属的模式名称
c、 form 后面可以跟多个表名,每个表名直接用逗号隔开即可
2、检索指定的列
如果想要显示指定的列而不是全部的列,并且被指定列的顺序不受限制,指定部分列也称为投影操作。需要把所显示的列紧跟在select 关键字后面,每个列名用逗号隔开。
语法:select column_name1,column_name2,column_name3... from table_name;
3、带有表达式的select 子句
在使用select 语句时,对于数字数据和日期数据都可以使用算数表达式,可以使用算数运算法,包括加、减、乘、除和括号操作。不仅可以执行单独数学运算,还可以执行单独的日期运算以及与列名关联的运算。
语法:select salary*(1+0.1,sal from emp;
4、为列指定列名
为了方便查看查询结果,可以为需要的列名指定别名。在 Oracle 系统中,可以使用as 关键字来指定别名,也可以什么也不用直接指定。
语法: select empno as "员工编号",ename "员工名称" from emp;
5、显示不重复记录
在默认情况下,结果集中包含所有符合查询条件的数据行,这样就可能出现重复的数据。在实际应用中,重复的数据可能不会带来太多的价值,需要去掉重复的记录,保留唯一记录即可。使用 distinct 即可实现。
语法: select distince job from emp;
二、筛选查询
在 select 语句中使用where 子句可以实现对数据行的筛选操作,只有满足where 子句中的判断条件才会显示在结果集中。
语法:
select columns_list from table_name where conditional_expression;
- columns_list:字段列表
- table_name:表名
- conditional_expression:筛选条件表达式
常用的集中筛选情况:
1、比较筛选
可以在 where 子句中使用比较运算符来筛选数据,这样只有满足条件的数据行才会被查询到,主要由下面6中情况:
a、A=B : 比较 A 与 B 是否相等
b、A!B 或 A <>B : 比较 A 与 B 是否不相等
c、A > B : 比较 A 是否大于 B
d、A < B :比较 A 是否小于 B
e、A >= B : 比较 A 是否大于或等于 B
f、A <= B : 比较 A 是否小于或等于 B
除了上面的6种,还有两个特殊的“比较筛选”操作
g、A { operator }ANY (B) :表示 A 与 B 中的任何一个元素进行operator 运算符的比较,只要有一个比较值为true,就返回数据行
h、A { operator } ALL (B):表示 A 与 B 中的所有元素都进行 operator 运算符的比较,只有与所有元素比较值都为 true,才返回数据行
下面看一个例子:
SQL > select empno,ename,sal from emp where sal <> all (3000,950,800);
表示从emp 表中使用 all 关键字过滤工资(sal) 同时不等于300、950和800的数据行。
2、使用特殊关键字筛选
SQL 语言提供了 like、in、between 和 isnull 等关键字来筛选匹配的数据,下面一项项来看:
(1)Like 关键字
在 where 子句中使用 like 关键字查询数据的方式也称为字符串模式匹配或字符串模糊查询。like 关键字需要使用通配符在字符串内查找指定的模式,常用的通配符有下划线 “_”,代表任意一个字符;百分号 “%”,代表任 意数量的字符。
EG: SQL> select name,job from emp where name like "S%" and job like "K_";
表示从emp表中查询 名字以 “S” 开头且任意长度的字符串,并且 job 是以 “K” 开头长度为 2 的字符串
注意:可以在 like 关键字前面加上 not,表示否定的判断,当然也可以在 in ,between ,isnull 和 isNAN 等关键字前面加上 not 来表示否定的判断。
(2)IN 关键字
当测试一个数据值是否匹配一组目标中的一个时,通常用 IN 关键字来指定列表搜索条件。
格式: value in (value1,value2,value3......)
EG : SQL > select name from job where name in ("Tom", "Emma","Tony");
表示从emp 表中查询 名字在列表中的数据行 。
(3)Between 关键字
需要返回某一个数据值是否位于两个给定的值之间,可以使用范围条件进行查询。通常使用 between... and 和 not between...and 来指定范围条件。
使用 between ....and 的条件时,指定的第一个值必须小于第二个值。其实等价于比较运算符(>= ... <=).
EG: SQL > select sal from emp where sal between 2000 and 3000;
表示从emp 表中查询工资大于等于2000并且小于等于3000的数据行。
(4)ISNULL关键字
空值(NUll)从技术上来说就是位置的、不确定的值,但空值与空字符串不同,空值是不存在的值,而空字符串是长度为 0 的字符串。
空值代表的是未知的值,但是并不能用空值来互相比较,这点需要特别注意。
EG: SQL > select address from student where address is null;
表示从 student 表中查询住址目前为空值的数据行
3、逻辑筛选
使用逻辑运算符 AND、OR、NOT可以进行逻辑筛选,可以把多个筛选条件组合起来,这样便于获取更加准确的数据记录。
AND 表示两个表达式之间 “逻辑与” 的关系,需要满足多个两个或者多个表达式才能成立。
OR 表示两个表达式“逻辑或” 的关系,两个表达式中有一个为 true,则这个逻辑表达式的值就为 true。
NOt 表示对表达式执行“逻辑非” 的运算。
三、分组查询
数据分组的目的是用来汇总数据或为整个分组显示单行的汇总信息,通常在查询结果集中使用 group by 子句对记录进行分组。
语法:
select columns_list from table_name [ where conditional_expression ] group by columns_list [ having contion_expression] ;
- column_list:字段列表,在 group by 子句中也可以指定多个列分组。
- table_name:表名
- condition_expression: 筛选条件表达式。
- having:该子句是对分组的再次筛选,只能用于group by 之后,而且可以使用常用的聚合函数
group by 子句可以基于指定某一列的值讲数据集合划分为多个分组,同一组内所有记录在分组属性上具有相同值,也可以基于指定多列的值将数据集合划分为多个分组。
EG:SQL > select deptno,job from emp group by deptno,job order by deptno;
表示按照部门编号(deptno) 和职务(job)列进行分组。
group by子句经常和聚合函数一起使用。
EG:SQL > select deptno as 部门编号,avg(sal) as 平均工资 from emp group by deptno;
表示按照部门进行分类,然后计算每一个部门的平均工资。
having子句可以进行再次筛选
EG:SQL > select deptno as 部门编号,avg(sal) as 平均工资 from emp group by deptno having avg(sal) > 200;
表示按照部门进行分组查询,然后通过having子句直接过滤出平均工资大于200的部门信息。
四、排序查询
查询数据时,查询结果将按照默认的顺序排列,往往并不能满足我们的需求。我们可以使用order by 子句对检索的结果进行排序。
语法:
select columns_list from table_name [ where conditional_expression ] [ group by columns_list ] [ order by { order_by_expression [ ASC| DESC ] } ] [,...n]
- columms_list: 字段列表,可以通过group by 子句指定多个列分组。
- table_name :表名
- condition_expression: 筛选条件表达式
- order_by-expression: 表示要排序的列名或者表达式。关键字 ASC 表示升序排列,默认的排序方式;DESC 表示降序排列。
order by 子句可以根据查询结果中的一个列或多个列对查询结果进行排序,并且第一个排序项是最主要的排序依据,剩下的是次要的排序依据。
EG:SQL > select deptno,empno from emp order by deptno ,empno;
表示先按照部门编号进行升序排序,如果有相同项,按照员工编号进行升序排序。
五、多表关联查询
在实际应用中查询数据可能会涉及多个数据表,每个表不是独立存在的,而是若干个表之间的信息存在一定的关系,当查询一个表的信息时,很可能需要查询关联数据表的信息,这就是多表关联查询。
1、表别名
在进行多表查询时,如果多个表之间存在同名的列,则必须使用表名来限定列的引用。SQL 语言提供了设定表别名的机制,使用简短的表别名就可以替代原有较长的表名称,可以大大缩短语句的长度。
EG:SQL > select e.empno as 员工编号,e.ename as 员工名称, d.dname as 部门 from emp e,dept d where e.deptno = d.deptno and e.job ="Manager";
表示通过部门号(deptno)来管理emp表和dept表,并查询这两个表中相关字段的信息。
注意:一旦在from 子句中为表指定了列名,则必须在剩余的子句中都使用表别名。
2、内连接
内连接是常用的多表关联查询,使用关键字inner join来实现,其中,inner 关键字可以省略,使用 join 即代表内联接。使用内联接查询多个表时,必须在 from 子句之后定义一个 on 子句,用来指定两个表实现内联接的“连接 条件”。
使用内联接进行多表查询时,返回的查询结果是只包含查询条件和连接条件的行,消除了与另一个表中任何行不匹配的行。
注意:在内联接的查询结果中,所有记录行都是满足连接条件的。
语法:
select column_list
from table_name1 [ innter ] join table_name2
on join_condition;
- columns_list : 字段列表
- table_name1 和 table_name2 :两个要实现内连接的表。
- join_condition: 实现内连接的条件表达式。
EG: SQL > select e.empno as 员工编号, e.ename as 员工名称,d.dname as 部门 from emp e inner join dept d on e.deptno = d.deptno;
表示通过 deptno 字段来连接emp 表和 dept表,并查询两个表中相关的字段。
3、外连接
多表之间进行外连接时,除了返回所有匹配的行外,还会返回一部分或全部不匹配的行,这主要取决于外连接的种类,主要由以下3种:
(1)、左外连接:关键字为left Outer join 或 left join
左外联接的结果集包括 LEFT OUTER子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值。
EG:select e.empon,e.ename,e.job,d.deptno,d.dname from emp e left join dept d on e.deptno = d.deptno;
表示从员工表(emp)表中查询出来所有的记录并查询部门表(dept)中两个deptno值相等的记录,如果没有相匹配的行,均为空值。
(2)右外连接:关键字为 right outer join 或 right join
右向外联接是左向外联接的反向联接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。
EG:select e.empno,e.ename,e.job,d.deptno,d.name from emp e right join dept d on e.deptno = d.deptno;
表示从部门表(dept)中查询出来所有的记录,并查询员工表(emp)表中与之deptno 对应的记录,如果没有匹配的行,均为空值。
(3) 完全外连接:关键字为 full outer join 或 full join
完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。
EG:select e.empno,e.ename,e.job,d.deptno,d.dname from emp e full join dept d on e.deptno = d.deptno;
表示查询两个表中所有的deptno的记录,如果对方的表中没有匹配的行,置为空值。
4、自然连接
自然连接是指在查询多个表时,Oracle 会将第一个表中的列与第二表中具有相同名称的列进行自动连接。自然连接中,用户不需要指定进行连续的列,这个任务由 Oracle 系统西段完成,自然连接使用“Natural join”关键字。
EG: select empno,ename,job,dname from emp natural join dept where sal > 200;
表示在emp表中查询工资(sal)大于2000的记录,并实现emp表与dept 表的自然连接。
注意:自然连接强制要求表之间必须具有相同的列名称,但是在实际开发中很少用到。在使用自然连接时,不能为列指定限定词(即表名或表的别名),否则Oracle 会报错。
5、自连接
在开发中,用户可能会拥有“自引用式”的外键,是指表中的一个列可以是该表主键的一个外键。
EG:
6、交叉连接
交叉连接实际上就是不需要任何连接条件的连接,它使用 cross join 关键字来实现。
语法: select colums_list from table_name1 cross join table_name2;
- colums_list : 字段列表
- table_name: 两个实现交叉连接的表名。
交叉连接的执行结果是一个笛卡尔积,这种查询非常冗余,但可以通过where 子句来过滤出有用的记录。
图解:
------------------------------------------------------------------------------------------------------------------------------------------------
表A Id name 表B ID job p_id
1 张三 1 25 1
2 李四 2 36 2
3 王五 3 36 4
a.id与b.p_id存在关系
-----------------------------------------------------------------------------------------------------------------------------------------------
(1)内连接
SQL > select a.*,b.* from a inner join b where a.id=b.p_id;
---------------------------------------------------------------------------------
a.Id a. name b.id b.job b.p_id
1 张三 1 25 1
2 李四 2 36 2
----------------------------------------------------------------------------------
(2)左外连接
SQL > select a.*,b.* from a left join b where a.id=b.p_id;
---------------------------------------------------------------------------------
a.Id a. name b.id b.job b.p_id
1 张三 1 25 1
2 李四 2 36 2
3 王五 null null null
----------------------------------------------------------------------------------
(3)右外连接
SQL > select a.*,b.* from a right join b where a.id=b.p_id;
---------------------------------------------------------------------------------
a.Id a. name b.id b.job b.p_id
1 张三 1 25 1
2 李四 2 36 2
null null 3 36 4
----------------------------------------------------------------------------------
(4)完全连接
SQL > select a.*,b.* from a full join b on a.id=b.p_id
---------------------------------------------------------------------------------
a.Id a. name b.id b.job b.p_id
1 张三 1 25 1
2 李四 2 36 2
null null 3 36 4
3 王五 null null null
----------------------------------------------------------------------------------
来源:https://www.cnblogs.com/niujifei/p/10921914.html