目录
1.SQL语言简介
特点:
分类:
编写规则
2.用户模式
模式与模式对象
示例模式scott
3.检索数据
简单查询
筛选查询
分组查询
排序查询
多表关联查询
4.Oracle常用系统函数
字符类函数
数字类函数
日期和时间类函数
转换类函数
聚合类函数
5.子查询的用法
什么是子查询
单行子查询
多行子查询
关联子查询
6.操作数据库
插入数据(INSERT语句)
更新数据(UPDATE语句)
删除数据(DELETE语句和TRUNCATE语句)
SQL语句通常用于完成一些数据库的操作任务,具有增加、删除、修改、数据定义与控制等完整的数据库操作功能。
1.集合性。在高层的数据结构上工作,而不对单个记录进行操作,可操作记录集。所有SQL语句接收集合作为输入,返回集合作为输出。
2.统一性。SQL为许多任务提供了统一的命令,方便学习和使用。数据库的操作任务通常包括以下几方面:
查询数据;
在表中插入、修改和删除记录;
建立、修改和删除数据对象;
控制对数据和数据对象的读写;
保证数据库一致性和完整性。
3.高度非过程化。SQL是一个非过程化的语言,没有循环结构和函数定义等功能,只提“做什么”,不管“怎么做”。
4.语言简单,易学易用。整个SQL语句只用9个命令动词即可实现对数据库及数据的查询和管理。如下表:
SQL的功能 | 命令动词 |
---|---|
数据定义 | CREATE,DROP,ALTER |
数据操纵 | SELECT,INSERT,UPDATE,DELETE |
数据控制 | GRANT,REVOKE |
5.以同一种语法结构提供两种使用方式。第一种是交互式应答使用,即用户在终端命令提示符下输入SQL命令时数据库服务器可以立即执行;第二种是通过预编译SQL进行执行,即把SQL命令嵌入到应用程序中执行。
6.是所有关系数据库的公共语言。所有主要的关系数据库管理系统都支持,所以是可移植的。
1.数据查询语言(DQL)
用于检索数据库中的数据,主要是select
2.数据操纵语言(DML)
用于改变数据库中的数据,主要是insert,update,delete
3.事务控制语言(TCL)
用于维护数据的一致性,主要是commit,rollback,savepoint(设置保存点)
4.数据定义语言(DDL)
用于建立、修改和删除数据库对象。主要是CREATE,DROP,ALTER。例如ALTER TABLE 修改表结构。
5.数据控制语言(DCL)
用于执行权限授予和权限收回操作。GRANT用于给用户或角色授予权限,REVOKE用于收回用户或角色所具有的权限。
SQL关键字不区分大小写;
对象名和列名不区分大小写;
字符值区分大小写;
SQL语句较长和分行显示,输入完毕要以分号作为结束符。
某个用户所创建的数据库对象(数据表,索引,视图等)都属于该用户模式,便于管理。
模式是一个数据库对象的集合。模式为一个数据库用户所有,并且名称相同。
模式对象是由用户创建的逻辑结构,用以存储或引用数据,如表,索引,约束,视图,同义词,过程,程序包等。
模式拥有模式对象。
该模式是Oracle提供的一个典型的示例模式,演示了一个很简单的公司人力资源管理的数据结构。
先查看scott用户是否存在:
alter user scott account unlock;
当scott用户不存在,
我们就需要在$ORACLE_HOME目录下寻找scott.sql文件,找到之后在命令行中执行文件:@ + 找到的文件位置
如果scott.sql文件都不存在(如上图),还可以执行urlsampl.sql文件创建scott用户,这个文件也位于$ORACLE_HOME/rdbms/admin文件夹下(执行之后会自动断开oracle的连接):
然后就可以了。
用默认密码"tiger"登录scott用户。
或者:
查看scott用户拥有的数据表:
检索数据我之前已经进行过整理,在这就简单总结一下,查漏补缺。
这是以前写的:数据库常用sql语句总结。
主要有7个子句:
group by 子句用于对检索结果进行分组显示
having子句用于从使用group by子句分组后的查询结果中筛选数据行。
1.检索所有的列,select * from 表名
2.检索指定的列,select col_name1,col_name2
3.带有表达式的select子句,select sal*(1+0.1)
4.为列指定别名,select empno as "员工编号",可去掉as
5.显示不重复记录,select distinct job from emp
6.处理null值,select ename,sal,comm,sal+nvl(comm,0) from emp
如果comm列存在数值,返回其原有数值,若为null,返回0
7.连接字符串,||或concat,select ename||'的工作是'||job from emp;
1.比较查询,=,!或<>,>,<,>=,<=
特殊:
A运算符ANY(B),A与B中任何一个元素进行比较,只要有一个比较值为true,返回数据行
A运算符ALL(B),A与B中所有元素进行比较,只有与所有元素的比较值为true,才返回数据行
2.使用特殊关键字筛选
LIKE:字符串模糊查询。通配符:%:代表0个或多个字符;_:只能代表一个字符。
IN:测试一个数据值是否匹配一组目标值中的一个。IN(目标值1,目标值2,...)。NOT IN表示不在某一组目标值中。
BETWEEN:某一数据值是否位于两个给定的值之间。BETWEEN...AND... ,NOT BETWEEN...AND...
IS NULL,不用=号判断null
3.逻辑筛选
AND OR NOT
GROUP BY
1.单列分组
group by 经常和聚集函数一起使用,可以实现对查询结果中每一组数据进行分类统计。
常用统计函数:AVG ,COUNT ,MAX ,MIN ,SUM
例如:在emp表中,对工资记录进行分组,并计算平均工资等。
select job,avg(sal),sum(sal),max(sal),count(job)
from emp
group by job;
2.多列分组
select deptno,job,avg(sal),sum(sal),max(sal)
from emp
group by deptno,job;
3.使用order by子句改变分组排序结果
4.使用having子句限制分组结果
类似于where,但是having可以包含聚合函数
select job,avg(sal),sum(sal),max(sal),count(job)
from emp
group by job
having avg(sal)>2000;
5.使用ROLLUP和CUBE操作符
group by只能生成简单的数据统计结果,这两个操作符可以生成横向小计,纵向小计和总计等
直接看例子:
ROLLUP:
CUBE:
GROUPING函数,查看是否使用了特定列(用到了多个列或没有用到任何列):
复合列:引用复合列时需要用括号括住相关列。使用复合列可以略过ROLLUP和CUBE操作符的某些统计结果。
---------------------
GROUPING SETS 操作符:为了显示多个分组的统计结果,就用该操作符合并分组结果:
ORDER BY
ASC 升序 ;DESC 降序
ORDER BY 语句和GROUP BY 语句都位于FROM语句之后,如果使用了GROUP BY 子句,则该子句一定是SQL语句的最后一个子句。
1.单列排序,不多说
2.多列排序
当以多列进行排序时,首先按照第一列进行排序,当第一列存在相同数据时,再以第二列进行排序,以此类推。
在此查询语句中,首先按照部门号排序,在同一个部门中,按照工地从高到低排序。
1.表的别名
多表关联时如果存在同名的列,需要用表名来限定列的引用,而为了避免语句冗长,就可以设定简短的表别名。
FROM子句最先执行,然后才是WHERE子句和SELECT子句,所以在FROM子句中指定表的别名后,其他所有子句都能使用。
别名一经定义,在整个查询语句中就只能使用别名不能使用表名,只在所定义的查询语句中有效。
2.内连接
返回的查询结果中只包含符合查询条件和连接条件的行。消除了与另一个表中的任何行不匹配的行。
FROM table_name1 [INNER] JOIN table_name2
ON join_condition;
3.外连接
除了返回所有匹配的行,还会返回一部分或全部不匹配的行,主要取决于外连接的种类。
左外连接 LEFT JOIN
右外连接 RIGHT JOIN
完全外连接 FULL JOIN
外连接不只列出与连接条件匹配的行,还能够列出左表(左外连接时)、右表(右外连接时)或两个表(完全外连接时)中所有符合搜索条件的数据行。
当使用“(+)”操作符执行外连接时,应该讲该操作符放在显示较少行(完全满足连接条件)的一端。
select e.empno,e.ename,e.job,d.deptno,d.dname
from emp e right join dept d
on e.deptno=d.deptno;
还可以这么写:
select e.empno,e.ename,e.job,d.deptno,d.dname
from emp e , dept d
where e.deptno(+)=d.deptno;
如果WHERE子句中包含多个条件,则必须在所有条件中都包含“(+)”操作符。
4.自连接
就是自己连接自己,主要用在自参考表上显示上下级关系或者层次关系。自参考表指的是在同一张表的不同列之间具有参照关系或主从关系的表。
例如,emp表包含empno(雇员号)和mgr(管理员号),两者之间就具有参照关系。
5.交叉连接
不需要任何连接条件,使用CROSS JOIN 关键字实现。
执行结果是一个笛卡尔积,非常冗余,但可以通过WHERE子句过滤出有用的记录信息。
ASCII(c) | 返回一个字符的ASCII码, CHR(i) 返回给出ASCII码值所对应的字符 |
CONCAT(s1,s2) | 将字符串s2连接到字符串s1的后面 |
INITCAP(s) | 将字符串s的每个单词的第一个字母大写,其他字母小写 |
INSTR(s1,s2[,i][,j]) | 返回字符串s2在字符串s1中第j次出现的位置,搜索从s1的第i个字符开始。未找到返回0,i为负从右往左搜索 |
LENGTH(s) | 返回字符串s的长度 |
LOWER(s)和UPPER(s) | 返回字符串s的小写形式和大写形式 |
LTRIM(s1,s2)、RTRIM(s1,s2)、TRIM(s1,s2) | 分别用来删除字符串s1左边、右边、两边的字符串s2。若不指定s2,表示去除相应地方的空格 |
REPLACE(s1,s2[,s3]) | 使用s3字符串替换出现在s1字符串中的所有s2字符串,并返回替换后的新字符串,s3默认值为空 |
SUBSTR(s,i[,j]) | 从字符串s的第i个位置开始截取长度为j的子字符串,省略参数j,则直接截取到尾部 |
ABS(n) | 返回n的绝对值 |
CEIL(n) | 返回大于或等于n的最小整数 |
COS(n) | 返回n的余弦值,n为弧度 |
EXP(n) | 返回e的n次幂 |
FLORR(n) | 返回小于或等于n的最大整数 |
LOG(n1,n2) | 返回以n1为底n2的对数 |
MOD(n1,n2) | 返回n1除以n2的余数 |
POWER(n1,n2) | 返回n1的n2次方 |
ROUND(n1,n2) | 返回舍入小数点右边n2位的n1的值,n2默认值为0 |
SIGN(n) | 若n为负数,返回-1,n为正数返回1,n为0返回0 |
SIN(n) | 返回n的正弦值,n为弧度 |
SORT(n) | 返回n的平方根,n为弧度 |
TRUNC(n1,n2) | 返回结尾到n2位小数的n1的值,n2默认值为0 |
举个例子:
ADD_MONTHS(d,i) | 返回日期d加上i个月之后的结果,i为整数 |
LAST_DAY(d) | 返回包含日期d月份的最后一天 |
MONTHS_BETWEEN(d1,d2) | 返回d1和d2之间的数目(通俗点就是d1减d2有几个月) |
NEW_TIME(d1,t1,t2) | 当t1和d1相同时,返回t2。d1时日期数据类型,t1和t2是字符串 |
SYSDATE() | 返回系统当前的日期 |
CHARTORWIDA | 将字符串s转换为RWID数据类型 |
CONVERT(s,aset[,best]) | 将字符串s由best字符集转换为aset字符集 |
ROWIDTOCHAR() | 将ROWID数据类型转换为CHAR类型 |
TO_CHAR(x[,format]) | 将表达式转换为字符串,format表示字符串格式 |
TO_DATE(s[,format[lan]]) | 将字符串s转换为date类型,format表示字符串格式,lan表示所使用的语言 |
TO_NUMBER(s[,format[lan]]) | 将返回字符串s代表的数字,format表示字符串格式,lan表示所使用的语言 |
AVG(x[DISTINCT|ALL]) | 计算选择列表项的平均值,列表项目可以是一个列或多个列的表达式 |
COUNT(x[DISTINCT|ALL]) | 返回查询结果中的记录数 |
MAX(x[DISTINCT|ALL]) | 返回选择列表项目中的最大数,列表项目可以是一个列或多个列的表达式 |
MIN(x[DISTINCT|ALL]) | 返回选择列表项目中的最小数,列表项目可以是一个列或多个列的表达式 |
SUM(x[DISTINCT|ALL]) | 返回选择列表项目的数值总和,列表项目可以是一个列或多个列的表达式 |
VARIANCE(x[DISTINCT|ALL]) | 返回选择列表项目的统计方差,列表项目可以是一个列或多个列的表达式 |
STDDEV(x[DISTINCT|ALL]) | 返回选择列表项目的标准偏差,列表项目可以是一个列或多个列的表达式 |
在执行数据操作(增删查改)的过程中,如果某个操作需要依赖于另外一个SELECT语句的查询结果,那么就可以把SELECT语句嵌入到该操作语句中,这样就形成了一个子查询。
子查询是在SQL语句内的另外一条SELECT语句,也称为内查询。在SELECT、INSERT、UPDATE、DELETE等命令中允许是一个表达式的地方都可以包含子查询,子查询甚至可以包含在另外一个子查询中。
比如,在SCOTT模式下,在emp表中查询部门名称(ename)为“RESEARCH”的员工信息。代码如下:
对以上代码进行分析,emp表是不存在dname字段(部门名称)的,但存在deptno字段(部门代码);dname字段原本存在于dept表中,dept表中也存在deptno字段,所以deptno为两个表之间的关联字段。所以本示例的需求也可以通过多表关联查询来实现。代码如下:
子查询的使用更加灵活、功能更强大并且易于理解;
多表关联查询的查询效率更高。(因为子查询语句需要检索一遍数据,然后判断外查询语句的条件是否满足,满足则添加到结果集,不满足则继续判断下一行数据)
单行子查询是指返回一行数据的子查询语句。
当在where子句中引用单行子查询时,可以使用单行比较运算符(=、>、<、>=、<=、<>)。
在emp表中,查出既不是最高工资,也不是最低工资的员工信息。
多行子查询是指返回多行数据的子查询语句。
当在where子句中使用多行子查询时,必须使用多行比较符(IN、ANY、ALL)。
使用IN运算符
外查询与子查询结果进行匹配,只要有一个匹配成功,则返回当前检索的记录
在emp表中,查询不是销售部门的员工信息
使用ANY运算符
必须与单行操作符结合使用,并且返回行只要匹配子查询的任何一个结果即可。
在emp表中,查询工资大于10号部门的任意一个员工工资的其他部门的员工信息。
使用ALL运算符
必须与单行操作符结合使用,并且返回行必须匹配所有子查询结果。
在emp表中,查询工资大于30号部门的所有员工工资的员工信息。
上述两种子查询中,内查询和外查询是分开执行的,外查询仅仅是使用了内查询的结果。在一些特殊需求的子查询中,内查询的执行需要借助于外查询,而外查询的执行又离不开内查询的执行。这时,内外查询是相互关联的,这种子查询就被称为关联子查询。
在emp表中,检索工资大于同职位的平均工资的员工信息。
在上面的查询语句中,内查询使用关联子查询计算每个职位的平均工资,而关联子查询必须知道职位的名称,为此外查询就使用f.job字段值为内查询提供职位名称。如果外层查询正在检索的数据行的工资高于平均工资,则该行的员工信息会显示出来。
单条插入数据:
a.使用列列表
insert into dept(deptno,dname,loc)
values(88,'design','beijing');
b.不使用列列表
insert into jobs values('PRO','程序员',5000,10000);
c.使用特定格式
insert into emp(empno,ename,job,hiredate)
values(1356,'MARY','CLERK',to_date(1983-10-20,'YYYY-MM-DD'));
d.使用DEFAULT提供数据
insert into dept values(60,'MARKET',DEFAULT);
如果列不存在默认值则为NULL
e.使用替代变量插入数据
accept no prompt '请输入雇员号:'
accept name prompt '请输入雇员名:'
accept title prompt '请输入雇员岗位:'
accept d_no prompt '请输入部门号:'
insert into emp(empno,ename,job,hiredate,deptno)
values(&no,'&name','&title',SYSDATE,&d_no);
批量插入数据:
insert into jobs_temp
select * from jobs
where jobs.max_salary >10000;
即使用INSERT语句和SELECT语句的组合可以一次性插入多条记录。
注意,两个语句对应的列之间,数据类型必须是兼容的,即select语句返回的数据必须满足insert into表中的约束。
更新单列数据:
update emp
set sal = 2460
where ename='SCOTT';
更新多列数据:
update emp
set sal = sal*1.2
where job='SALESMAN';
列之间用逗号隔开。
更新日期列数据:
update emp
set hiredate = TO_DATE('1984/01/01','YYYY/MM/DD')
where empno=7788;
使用DEFAULT选项更新数据:
update emp
set job = DEFAULT
where ename='SCOTT';
如果列不存在默认值则为NULL。
使用子查询更新数据:
同INSERT语句一样,UPDATE语句也可以与SELECT语句组合使用。
update emp
set sal = (select avg(sal)
from emp where job = 'MANAGER')
where sal < 2000;
delete语句:删除数据库中的所有记录和指定范围的记录(通过WHERE子句进行限制)。
delete from jobs where job_id='PRO';
delete from emp;
TRUNCATE语句:删除表中的所有记录。
比DELETE快得多,因为它不会产生回滚记录,不能用ROLLBACK语句撤销。
truncate table jobs_temp;