当前位置:首页 » 《休闲阅读》 » 正文

关系型数据库与非关系型数据库的分类以及oracle数据库语法总结_m0_58032275的博客

3 人参与  2022年02月04日 14:33  分类 : 《休闲阅读》  评论

点击全文阅读


数据库(Oracle)


​ 开发组成 :前端 后端 数据库

​ 数据库分类
​ 关系型数据库(把复杂的数据结构归结为简单的二元关系即二维表格形式,对数据的操作几乎全部建立在一个或多个
​ 关系表格上,通过对这些关联的表格分类、合并、连接、或选取来实现数据库的管理。

​ 传统实例:Oracle 、Mysql 、Microsoft SQL Server…

​ 非关系型数据库(NoSQL泛指非关系型数据库): 传统关系型数据库在应付web2.0网站,特别是超大规模和高并发SNS类型
​ 的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库由于其本身特点得到迅速发展
​ 。Nosql数据库在特定的场景下可以发挥出难以想象的高效率和高性能,它是作为对传统关系型数据库的一个有效的补充

​ 分类:(1)键值(key-value)存储数据库 Redis
​ (2)列存储(Column-oriented)数据库
​ (3)面向文档数据库 MongoDB CouchDB
​ (4)图形数据库 Neo4j InforGird
​ (5)时序数据库InfluxDB Prometheus OpenTSDB(底层基于HBase)

	···			数据库发展阶段
					人工管理阶段
					文件系统阶段
					数据库系统阶段

				数据库的主要特点有:

					1. 实现数据共享
					数据共享包含所有用户可同时存取数据库中的数据,也包括用户可以用各种方式通过接口使用数
					据库,并提供数据共享。
					2. 减少数据的冗余度
					同文件系统相比,由于数据库实现了数据共享,从而避免了用户各自建立应用文件。减少了大量
					重复数据,减少了数据冗余,维护了数据的一致性。
					3. 数据的独立性
					数据的独立性包括数据库中数据库的逻辑结构和应用程序相互独立,也包括数据物理结构的变化
					不影响数据的逻辑结构。
					4. 数据实现集中控制
					文件管理方式中,数据处于一种分散的状态,不同的用户或同一用户在不同处理中其文件之间毫
					无关系。利用数据库可对数据进行集中控制和管理,并通过数据模型表示各种数据的组织以及数
					据间的联系。
					5. 数据一致性和可维护性,以确保数据的安全性和可靠性
					安全性控制:以防止数据丢失、错误更新和越权使用;
					完整性控制:保证数据的正确性、有效性和相容性;
					并发控制:使在同一时间周期内,允许对数据实现多路存取,又能防止用户之间的不正常
					交互作用;
					故障的发现和恢复:由数据库管理系统提供一套方法,可及时发现故障和修复故障;
					6. 故障恢复
					由数据库管理系统提供一套方法,可及时发现故障和修复故障,从而防止数据被破坏。数据库系
					统能尽快恢复数据库系统运行时出现的故障,可能是物理上或是逻辑上的错误。比如对系统的误
					操作造成的数据错误等。

			

3.数据库对象

数据库对象是数据库的组成部分,常常用 CREATE 命令进行创建,可以使用 ALTER 命令修改,用 DROP执行删除操作。常见的数据库对象有:

用户(user)

表(table)

视图(view)

索引(index)

触发器(trigger)

存储过程(procedure)

同义词(synonym)

序列(sequence)

在学习的过程中,所接触到的内容,都与这些oralce数据库对象有关系

4.sql

SQL(Structured Query Language),结构化查询语言,是专门操作关系型数据库的一种语言
				第一代编程语言,机器语言,是面向机器的,通过二进制代码对其计算机操作
				第二代编程语言, 汇编语言,使用指令对应的符号,来代替二进制代码
				第三代编程语言,高级开发语言 ,例如C、C++ Java等,语言更加简单,操作更方便
				第四代编程语言,只告诉计算机需要做什么,不需要告诉计算机怎么做,更加接近自然语言

			例如:select name from tbl_student;
			这时候只是告诉计算机,我们需要查看表中的name字段的值,但是没说该怎么做

			sql语句的分类:

				DQL (Data Query Language),数据查询语言
				用于检索数据库中的数据,主要是 SELECT 语句
				DML (Data Manipulation Language),数据操纵语言
				用于改变数据库中的数据,主要是 INSERT , UPDATE , DELETE 语句
				DDL(Data Define Langage),数据定义语言
				用来建立、修改、删除数据库对象,主要是 CREATE 、 ALTER 、 DROP 、 TRUNCATE 语句
				TCL (Transaction Control Language),事务控制语言
				用于维护数据的一致性,主要是 COMMIT , ROLLBACK , SAVEPOINT 语句
				DCL(Data Control Language),数据控制功能
				用于执行权限授予和权限收回操作,主要是 GRANT , REVOKE 语句

				注意,DML语句需要事务的支持(产生事务),DDL语句会自动提交事务
				
				sql、sqlplus、pl/sql的区别:
				sql,结构化的查询语句,操作关系型数据库的语言
				sqlplus,oracle数据库软件自带工具,可以接收用户输入的sql语句,然后将sql执行结果显示出来
				pl/sql,程序化的sql语句,在sql语句的基础上加入一定的逻辑操作,如 if for 等

			不同的关系型数据库中,sql语句的基本语法都是相同的,但是在特殊的情况下,也会有稍许差异

select

1 基础

select语句,可以通过列名,把一行行的数据给查询出来,语法为:

select [distinct] *{col_name1,col_name2,..} from tb_name;

注意1,语法中出现的中括号[],表示该部分可有可无

注意2,*号表示所有列

注意3,col_name1,col_name2代表列名,如果有多个可以逗号分开

例如,查看所有员工的id,名字(last_name)和薪资(salary)

select id,last_name,salary
from s_emp;

运算

例如,查看每个员工的员工id,名字和年薪

select id,last_name,salary*12

from s_emp; 

注意,select语句永远不会对原始数据进行修改;

例如,查看每个员工的员工id,名字和月薪涨100以后的年薪

select id,last_name,(salary+100)*12
from s_emp;

别名

语法:

select old_column [as] new_column_name from tb_name; 

注意,中括号里面的as是可选的

例如,查看员工的员工id,名字和年薪,年薪列名为annual

select id,last_name,salary*12 as annual
from s_emp;

或者

select id,last_name,salary*12 annual
from s_emp;

拼接

​ 语法:

select col_name||'spe_char'||col_name from tb_name

例如,查看员工的员工id,全名

select id,first_name||last_name
from s_emp;

例如,查看员工的员工id,全名和职位名称,全名和职位名称合并成一列显示,且格式为:姓名,职位

名称

select id,first_name||' '||last_name||','||title as name
from s_emp;

nvl

使用nvl函数可以将null进行替换

语法:

select nvl(col_name,change_value) from tb_name;

例如,查看所有员工的员工id,名字和提成,如果提成为空,显示成0

select id,last_name,nvl(commission_pct,0) commission_pct
from s_emp;

distinct

该关键字可以将重复数据去除。

语法:

select distinct col_name,col_name...
from tb_name;

例如,下面sql的语法错误!

select id,distinct title
from s_emp;

如果 distinct 关键词后面如果出现多列,表示多列联合去重,即多列的值都相同的时候才会认为是重

复的记录。

//test表中的数据为: 

id id2 

1 2 

1 3 

2 4 

3 4 

3 4 

select distinct id,id2

from test; 

//查询结果为: 

id id2 

1 2 

1 3 

2 4
3 4

例如,查看所有员工的职位名称和部门id,同职位同部门的只显示一次

select distinct dept_id,title
from s_emp;

format

使用 format 可以将查询结果显示的宽度进行调整。

例如

select id,last_name
from s_emp;

运行结果为:

ID LAST_NAME
---------- --------------------------------------------------
1 Velasquez 
2 Ngao 
3 Nagayama 
4 Quick-To-See 
5 Ropeburn 
6 Urguhart 
7 Menchu

使用 format 调整last_name列所占的宽度,其实就是“-”的个数

例如

//表示last_name列的下方有15个“-”
column last_name format a15 
//或者简写为 
col last_name for a15; select id,last_name
from s_emp;

运行结果:

ID LAST_NAME
---------- ---------------
1 Velasquez 
2 Ngao 
3 Nagayama 
4 Quick-To-See 
5 Ropeburn 
6 Urguhart 
7 Menchu ......

可以清除设置的格式:

clear column //或者 clear co

注意,format只能设置字符类型的字段列

sqlplus

使用 sqlplus 登录之后,可以使用buff(缓存)来存储/执行/修改上一条运行的sql语句 。

buff中只能存储一条sql语句,但是这条sql语句可能有很多行

每次放入新的sql语句,会把之前的覆盖掉

每次执行sql语句,都会把这个sql语句放到buff里面

sqlplus 相关的命令:

l 查看缓存中的sql语句

a 在[定位]的那一行后面追加新的内容

i 在[定位]的那一行下面插入新的一行

c 替换[定位]的那一行中的某些字符串 ,格式为:c/老的字符串/新的字符串

del 删除[定位]的那一行内容

n 后面加内容可以重写这一行

$ 后面跟一个终端命令,例如$cls清屏,linux中使用! 

/ 执行缓存sql命令

注意,使用 l 命令查看buff中的sql后,可以直接输入行数,然后回车,这就是定位到了这一行

如果要清空buff中的sql:

clear buffer

其他的一些命令:

save test.sql //buff中的sql语句保存在test.sql文件中 
get test.sql //把test.sql中的内容在加载到buff中,但是没有运行 
start test.sql //把test.sql中的内容在加载到buff中并且执行 
@test.sql //把test.sql中的内容在加载到buff中并且执行 
edit file_name //使用系统默认编辑器去编辑文件

spool 命令:可以记录操作的过程

spool file_name //将接下来的sql语句以及sql的运行结果保存到文件中 
sql1 result1 sql2 result2 ... spool off //关闭spool功能

排序

查询数据的时候进行排序,就是根据某个字段的值,按照升序或者降序的情况将记录显示出来

语法:

select col_name,...
from tb_name order by col_name [asc|desc]

注意1,order by语句,只对查询记录显示调整,并不改变查询结果,所以执行权最低,最后执行

注意2,排序的默认值是asc:表示升序,desc:表示降序

注意3,如果有多个列排序,后面的列排序的前提是前面的列排好序以后有重复(相同)的值。

例如,

//假设test表中有以下数据 
id id2 
1 2 
2 3
3 4
4 1
4 2
select id,id2
from test 
order by id asc,id2 desc; 
//查询结果: 
id id2 
1  2  
2  3
3  4
4  2
4  1

注意,先升序排第一列,如果第一列有重复的值,再降序排第二列,以此类推

注意,上面的asc可以省去不写,因为是默认值

例如,查看员工的id,名字和薪资,按照薪资的降序排序显示,工资相同就按名字升序排

select id,last_name,salary
from s_emp 
order by salary desc,last_name;

条件查询

语法:

select col_name,...
from tb_name 
where col_name 比较操作表达式

注意1,限制查询条件,使用where子句

注意2,条件可以多个,使用逻辑操作符或者小括号进行条件的逻辑整合

注意3,where子句的优先级别最高

注意4,比较操作表达式由操作符和值组成

逻辑比较操作符= > < >= <= !=

不等于操作符,以下三个都表示不等于的意思,经常用的是 !=

!= <> ^=

例如,查看员工工资小于1000的员工id和名字

select id,last_name,salary

from s_emp 

where salary < 1000;

between and 操作符,表示在俩个值之间

例如,查看员工工资在700 到 1500之间的员工id和名字

select id,last_name,salary
from s_emp 
where salary between 700 and 1500;

in() ,表示值在一个指定的列表中

例如,查看员工号1,3,5,7,9员工的工资

select id,last_name,salary
from s_emp 
where id in (1,3,5,7,9);

like ,模糊查询,在值不精确的时候使用

% ,通配0到多个字符

_ ,通配一个字符,并且是一定要有一个字符

\ ,转义字符,需要使用 escape 关键字指定,转义字符只能转义后面的一个字符

例如,查看员工名字以C字母开头的员工的id,工资

select id,last_name,salary
from s_emp 
where last_name like 'C%';

注意,数据库中的字符串,需要使用单引号括起来

例如,查看员工名字长度不小于5,且第四个字母为n字母的员工id和工资

select id,last_name,salary
from s_emp where last_name like '___n_%';

例如,查看员工名字中包换一个_的员工id和工资

select id,last_name,salary
from s_emp where last_name like '%\_%' escape '\';

is null ,判断值为null的时候使用,null值的判断不能使用等号

例如,查看员工提成为为空的员工的id和名字

select id,last_name,commission_pct
from s_emp 
where commission_pct is null;

注意,类似的,还有 is not null

and 、 or ,逻辑操作符,当条件有多个的时候可以使用

注意,and比or的优先级要高

例如,查看员工部门id为41且职位名称为Stock Clerk(存库管理员)的员工id和名字

select id,last_name,dept_id,title
from s_emp 
where dept_id = 41 and title = 'Stock Clerk';

例如,查看员工部门为41 或者 44号部门,且工资大于1000的员工id和名字

select id,last_name,dept_id,title
from s_emp 
where salary > 1000 and (dept_id = 41 ordept_id = 44 );

例如,查看员工部门为41且工资大于1000,或者44号部门的员工id和名字

select id,last_name,dept_id,title
from s_emp 
where salary > 1000 and dept_id = 41 ordept_id = 44;

注意,以上俩个sql语句,执行的结果是不一样的,它们的区别就是第一个sql在条件中多了个小括

查询s_emp表中最大工资数,并且显示出这个最大工资的员工的名字

select max(s1.salary),s2.last_name
from s_emp s1,s_emp s2
group by s2.salary,s2.last_name
having max(s1.salary) =s2.salary;

第一步,查出最大工资数

select max(salary)
from s_emp;

第二步,加上last_name的显示

select last_name,max(salary)
from s_emp;

第三步,select后面出现组函数,没有被组函数修饰的列放到group by后面,

select last_name,max(salary)
from s_emp 
group by last_name;

注意,这时候会发现查询结果并不是想要结果,因为这是按名字分组,每个人的名字都不同,那

么就是每一个人就是一个小组。其实表里有俩个人的名字都叫Patel,所以本来25条数据,这时候

会查出24条

第四步,修改为多表查询(起别名),从s1表中查询出最大的工资数是多少,然后再和s2表连接起来,选

出s2表中这个最大工资数的员工名字

select s2.last_name,max(s1.salary)
from s_emp s1,s_emp s2 
where s2.salary = max(s1.salary) 
group by s2.last_name;

注意,这时候会报错,因为where后面不能出现组函数

第五步,where后面不能出现组函数,所以改为having

select s2.last_name,max(s1.salary)
from s_emp s1,s_emp s2 
group by s2.last_name,s2.salary 
having s2.salary = max(s1.salary); 
//运行结果: LAST_NAME MAX(S1.SALARY)
--------------------- --------------
Velasquez 2500

例如,查询s_emp表每个部门的最大工资数,并且显示出这个最大工资的员工的名字,以及该部门的名

字、该部门所属区域,并且使用部门编号进行排序

select
	max(s1.salary),s2.last_name,s2.dept_id,sr.name,sd.name
from
	s_emp s1,s_emp s2,s_dept sd,s_region sr
where
	s1.dept_id =s2.dept_id
and
	s1.dept_id=sd.id
and
	sd.region_id = sr.id
group by
	s2.dept_id,s2.last_name,s2.salary,sr.name,sd.name
having
	max(s1.salary) =s2.salary
order by
	s2.dept_id;

oracle(2)函数、多表查询、结果集、伪列

常用函数分类(三类)

1.单行函数

  • 字符函数
  • 日期函数
  • 数字函数

2.转换函数

3.聚合函数

常用函数用法

单行函数,也可以称为单值函数,每操作一行数据(某个字段值),都会返回一个结果

例如,查询id小于5的员工信息(id、last_name、salary)

select id,last_name,salary

from s_emp 

where id<5; 
//运行结果:ID LAST_NAME SALARY
---------- --------------- ----------
1 Velasquez 2500 
2 Ngao 1450 
3 Nagayama 1400 
4 Quick-To-See 1450

例如,使用单行函数,将上面的结果中每一个last_name转换为大写

select id,upper(last_name) as last_name,salary
from s_emp 
where id<5; 
//运行结果:
ID LAST_NAME SALARY
---------- --------------- ----------
1 VELASQUEZ 2500 
2 NGAO 1450 
3 NAGAYAMA 1400 
4 QUICK-TO-SEE 1450

可以看到,单行函数,对每一行中的last_name字段值都进行了操作,并返回了转换结果

  • 字符函数 (常用)
    • ASCII(X) 返回字符X的ASCII码
    • CONCAT(X,Y) 连接字符串X和Y
    • INSTR(X,STR[,START][,N) 从X中查找str,可以指定从start开始,也可以指定从n开始
    • LENGTH(X) 返回X的长度
    • LOWER(X) X转换成小写
    • UPPER(X) X转换成大写
    • INITCAP(X) X首字母转换为大写,其他字母小写
    • LTRIM(X[,TRIM_STR]) 把X的左边截去trim_str字符串,缺省截去空格
    • RTRIM(X[,TRIM_STR]) 把X的右边截去trim_str字符串,缺省截去空格
    • TRIM([TRIM_STR FROM]X) 把X的两边截去trim_str字符串,缺省截去空格
    • REPLACE(X,old,new) 在X中查找old,并替换成new
    • SUBSTR(X,start[,length]) 返回X的字串,从start处开始,截取length个字符,缺省length,默认到结尾

例子:INSTR(X,STR[,START][,N) ,从X中查找str,可以指定从start开始,也可以指定从n开始

select instr('Hello World','o') as result 
from dual; 
//运行结果: 
RESULT
----------
5

select instr('Hello World','o',6) as result 
from dual; 
//从前往后查找,从下标为6开始 
//运行结果: 
RESULT
----------
8

select instr('Hello World','o',-1) as result 
from dual; 
//从后往前查找,从最后一个开始 
//运行结果: 
RESULT
----------
8
  • 数字函数(专门操作数字的函数,常用)

    • INITCAP(X) X首字母转换为大写,其他字母小写
    • LTRIM(X[,TRIM_STR]) 把X的左边截去trim_str字符串,缺省截去空格
    • RTRIM(X[,TRIM_STR]) 把X的右边截去trim_str字符串,缺省截去空格
    • TRIM([TRIM_STR FROM]X) 把X的两边截去trim_str字符串,缺省截去空格
    • REPLACE(X,old,new) 在X中查找old,并替换成new
    • SUBSTR(X,start[,length]) 返回X的字串,从start处开始,截取length个字符,缺省length,默认到结尾

例子:INSTR(X,STR[,START][,N) ,从X中查找str,可以指定从start开始,也可以指定从n开始

select instr('Hello World','o') as result 
from dual; 
//运行结果: 
RESULT
----------
5

select instr('Hello World','o',6) as result 
from dual; 
//从前往后查找,从下标为6开始 
//运行结果: 
RESULT
----------
8

select instr('Hello World','o',-1) as result 
from dual; 
//从后往前查找,从最后一个开始 
//运行结果: 
RESULT
----------
8
  • 数字函数(专门操作数字的函数,常用)

在这里插入图片描述
日期函数

  • sysdate ,是Oracle中用来表示当前时间的关键字,并且可以使用它来参与时间运算。

    例如,

    //显示当前时间
    select sysdate from dual;
    

    例如,

    //显示时间:明天的这个时候
    select sysdate + 1 
    from dual; 
    //显示时间:昨天的这个时候 
    select sysdate - 1 
    from dual; 
    //显示时间:1小时之后的这个日期 
    select sysdate + 1/24 
    from dual;
    

    注意, sysdate 参与时间的加减操作的时候,单位是天

    特别注意,oracle中不同的会话环境中,日期数据默认的格式也不同

中文

SQL> alter session set nls_language='simplified chinese'; 
会话已更改。 
SQL> select sysdate 
from dual; 
SYSDATE
--------------
02-9-20 
SQL>

注意,观察中文环境的会话中的默认日期格式的特点。

英文

SQL> alter session set nls_language=english; 
Session altered. 
SQL> select sysdate 
from dual; 
SYSDATE
------------
02-SEP-20 
SQL>
**常见的日期函数**

在这里插入图片描述
months_between

例如,30天之后和现在相差多少个月

select months_between(sysdate+30,sysdate) as result
from dual; 
//运行结果: 
RESULT
----------
1

add_months

例如,指定日期,往后推2个月

alter session set nls_language='simplified chinese'; 
select add_months('01-10月-2020',2) as result
from dual; 
//运行结果: 
	RESULT
--------------
01-12-20
alter session set nls_language=english; 
select add_months('01-OCT-2020',2) as result
from dual; 
//运行结果:
	RESULT
------------
01-DEC-20

注意,这个数字也可以是负数,表示之前多少月

2.转换函数

转换函数,可以将一个类型的数据,转换为另一种类型的数据

转换函数主要有三种:

  1. TO_CHAR ,把一个数字或日期数据转换为字符
    在这里插入图片描述
    select to_char(salary,’$999,999.00’) as result
    from s_emp;

//运行结果:
RESULT

$2,500.00
$1,450.00
$1,400.00
$1,450.00
$1,550.00

select to_char(salary,‘L999,999.00’) as result
from s_emp;
//运行结果:
RESULT

¥2,500.00
¥1,450.00
¥1,400.00
¥1,450.00
¥1,550.00

select to_char(-10,‘999PR’) as result
from dual;
//运行结果:
RESULT

<10>
日期转为字符的常用格式:
在这里插入图片描述
例如

select to_char(sysdate,'yyyy mm MONTH mon MON D DD DDD DAY DY')
from dual;
select to_char(sysdate,'dd-mm-yy')
from dual;
select to_char(sysdate,'yy-mm-dd')
from dual;
select to_char(sysdate,'yy-mm-dd hh24:mi:ss')
from dual;
select to_char(sysdate,'yy-mm-dd hh:mi:ss AM')
from dual; 

2.TO_NUMBER ,把字符转换为数字

例如,

select to_number('1000')   //不能写abc这种字符,不能转换为数字,会报错
from dual;
  1. TO_DATE ,把字符转换为日期

    select to_date('10-12-2022','dd-mm-yyyy') as result
    
    from dual; 
    
    alter session set nls_language='simplified chinese'; 
    select to_date('25-5月-22','dd-month-yy') as result
    from dual;
    

聚合函数,也可以称为多行函数、分组函数、组函数,它可以操作多行数据,并返回一个结果,一般会

结合着group分组来使用,当然也可以单独使用,那么默认全部数据就是一个小组。

例如,查询id小于5的所有员工的平均工资

select avg(salary)

from s_emp 

where id<5; 

//运行结果: 

AVG(SALARY)

\-----------

1700 

例如,查询每个部分的员工人数、以及该部门的平均工资,并且按照平均工资的降序排序

select dept_id,count(*),avg(salary) as avgSalary
from s_emp 
group by dept_id 
order by avgSalary desc;

//运行结果:
DEPT_ID COUNT(*) AVGSALARY
---------- ---------- ----------
50 2 2025 
33 1 1515 
32 1 1490 
10 1 1450 
35 1 1450 
31 2 1400 
41 4 1247.5 
34 2 1160 
45 3 1089 
42 3 1081.66667 
44 2 1050 
DEPT_ID COUNT(1) AVGSALARY
---------- ---------- ----------
43 3 900

2.6 函数嵌套

以上介绍的常用函数,在数据类型正确的情况下,是可以嵌套使用的。

例如,先把’hello’和’world’连接起来,再转换为全部字母大写,然后再从第4个字符开始,连着截取4个字符

select substr(upper(concat('hello','world')),4,4) as result
from dual;

注意,函数f1的返回类型,必须是函数f2的参数类型,那么它们之间才可以嵌套

哑表

Oracle中,有一张特殊的表:dual

dual被称之为哑表,它是一个单行单列的虚拟表,是Oracle内部自动创建的,这个表只有1列:DUMMY,

数据类型为VERCHAR2(1),dual表中只有一个数据’X’,Oracle有内部逻辑保证dual表中永远只有一条数

据。

在实际使用中,Dual表主要用来选择系统变量或求一个表达式的值,因为要使用dual来构造完成的查询

语法

例如,查询表达式1+1的结果

select 1+1 
from dual; 
//运行结果:
1+1
----------
2

注意,按照sql语句的要求,没有表就没法查询,而表达式1+1,不属于任何表,那么就有了哑表

dual的概念了

3 多表查询

多表查询,又称表联合查询,即一条sql语句涉及到的表有多张,表中的数据通过特定的连接,进行联合显示

3.1 笛卡尔积

在数学中,两个集合X和Y的笛卡尓积(Cartesian product),又称直积,表示为X × Y

例如,假设集合A={a, b},集合B={0, 1, 2},则两个集合的笛卡尔积为{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b,

2)}。

在数据库中,如果直接查询俩张表,那么其查询结果就会产生笛卡尔积。

例如,

select count(*)
from s_emp; 
select count(*)
from s_dept; 
select count(*)
from s_emp,s_dept;

注意,s_emp表中25条数据,s_dept表中12条数据,查询俩张表,数据俩俩组合,会得到300条数据

其实,s_emp表中的每一条数据,和s_dept表中的每一条数据进行俩俩组合,这里面大多数的数据是没

有意义的,为了这种避免笛卡尔积的产生,在多表查询的时候,可以使用连接查询来解决这个问题。

连接查询又可以大致分为:

  1. 等值连接

    利用一张表中某列的值,和另一张表中某列的值相等的关系,把俩张表连接起来,满足条件的数据才会组合

    例如,查询员工的名字、部门编号、部门名字

    select last_name,dept_id,s_dept.id,name
    from s_emp,s_dept 
    where s_emp.dept_id=s_dept.id;
    
  2. 不等值连接

  3. 外连接

    左外连接

    右外连接

    全连接

  4. 自连接

嵌套查询

查询工资 大于Simth的

select salary,last_name
from s_emp
where salary>(
select salary
    from s_emp
    where last_name='Smith'
);

例如,查询平均工资比 41号部门的平均工资 高 的部门中员工的信息

第一步,查询41号部门的平均工资

select avg(salary)
from s_emp 
where dept_id=41;
//运行结果: AVG(SALARY)
-----------
1247.5

第二步,查询平均工资比1247.5高的部门编号

select dept_id
from s_emp 
group by dept_id 
having avg(salary)>1247.5; 
//运行结果: DEPT_ID
----------
313235503310 已选择6行。

第三步,查询平均工资比1247.5高的部门中员工信息

select last_name,salary,dept_id
from s_emp 
where dept_id in(10,31,32,33,35,50);

第四步,把in条件后的数据进行替换

select last_name,salary,dept_id
from s_emp 
where dept_id in( 
    select dept_id
	from s_emp 
    group by dept_id 
    having avg(salary)>1247.5 
);

第五步,把1247.5进行替换

select last_name,salary,dept_id
from s_emp 
where dept_id in(
   select dept_id
   from s_emp 
   group by dept_id 
   having avg(salary)>(
       select avg(salary)
   	from s_emp 
       where dept_id=41 )
);

分页查询

伪列

select t.id,t.last_name,t.dept_id

from (

select rownum rn,id,last_name,dept_id

from s_emp 

where rownum<=10 

) t 

where t.rn>=6; 

点击全文阅读


本文链接:http://zhangshiyu.com/post/34273.html

数据  员工  函数  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1