Oracle 基础总结(上)
第二章 Oracle表及表空间
第一节:Oracle 表空间
一个数据库可以有多个表空间,一个表空间里可以有多个表。表空间就是存多个表的物理空间;
可以指定表空间的大小位置等。
第三节:Oracle 虚拟表 dual 表
Dual表是 sys 用户下的一张虚表;提供一些运算和日期操作时候用到;
select sysdate from dual;
第三章 Oracle序列
序列作为数据库里的对象,主要作用是生成唯一的主键值;
第二节:创建序列
create sequence 序列名称;
重要属性: 序列名称.currval 当前值 nextval 下一个值
指定初始值: start with xx
Increment by 属性 序列增长步长 默认值 1
Cache 缓存设置; 一次获取序列的多个连续值,默认 20 ,放到内存中,方便下次快速获取;
第四章 Oracle表操作
第五节:查询 select语句
Distinct 去重复记录;
Group by分组查询:select job,count(ename) as num from EMP t group by job;
Having过滤分组:select job,count(ename) as num from EMP t group by job having count(ename)>=2;
联合查询:
并集(去重复):
select * from t_user1
union
select * from t_user2;
并集:
select * from t_user1
union all
select * from t_user2;
交集:
select * from t_user1
intersect
select * from t_user2;
差集:
select * from t_user1
minus
select * from t_user2;
内连接:
select * from emp t,dept d where t.deptno=d.deptno; (在oracle中效率不高)
类似:select * from emp e inner join dept d on e.deptno=d.deptno;(inner 可以省略; 推荐使用)
第五章 Oracle数据类型及函数
第一节:字符串类型及函数
字符类型分 3 种,char(n) 、varchar(n)、varchar2(n) ;
char(n)固定长度字符串,假如长度不足 n,右边空格补齐;
varchar(n)可变长度字符串,假如长度不足 n,右边不会补齐;
varchar2(n)可变长度字符串,Oracle 官方推荐使用,向后兼容性好;
char(n) VS varchar2(n) char(n)查询效率相对较高,varchar2(n)存储空间相对较小;
lpad() 向左补全字符串:select lpad(stuno,6,'0') from t_user3;
rpad() 向右补全字符串:select rpad(stuno,6,'0') from t_user3;
lower() 返回字符串小写:select lower(userName) from t_user3;
upper() 返回字符串大写:select upper(userName) from t_user3;
initcap() 单词首字符大写:select initcap(userName) from t_user3;
length() 返回字符串长度:select length(password) from t_user3;
substr() 截取字符串:select substr(userName,1,2) from t_user3; (索引从1开始)
instr() 获取字符串出现的位置:select instr(password,'23',2,2) from t_user3; (从第2个位置,第2次出现的)
ltrim() 删除左侧空格:select ltrim(userName) from t_user3;
rtrim() 删除右侧空格:select rtrim(userName) from t_user3;
trim() 删除两侧空格:select trim(userName) from t_user3;
concat() 串联字符串:select concat(userName,password) from t_user3;
reverse() 反转字符串:select reverse(userName) from t_user3;
第二节:数值类型及函数
number是 oracle中的数据类型;number(precision,scale);
Precision,scale 均可选;
Precision 代表精度,sacle代表小数位的位数;Precision 范围[1,38] scale范围[-84,127]
举例: 12345.678 Precision 是 8 scale 是 3;
常用方法:
abs() 求绝对值;select abs(n1) from t_number where id=1;
round() 四舍五入:select round(n1,2) from t_number where id=1;
ceil() 向上取整:select ceil(n1) from t_number where id=2;
floor 向下取整:select floor(n1) from t_number where id=2;
Mod()取模:select mod(5,3) from dual; (求余数)
Sign()正负性:select sign(n1) from t_number where id=1;
Sqrt() 求平方根:select sqrt(9) from dual;
Power()求乘方:select power(2,3) from dual;
Trunc()截取:select trunc(123.456,2) from dual; (截取小数位,默认是0,不四舍五入)
To_char() 格式化数值:常见的字符匹配有 0、9、,、$、FM、L、C
select to_char(123.45,'0000.000') from dual; -----0123.450
select to_char(123.45,'9999.999') from dual; -----123.450 (整数位前面不补0)
select to_char(123123,'99,999,999.99') from dual; ----- 123,123.00
select to_char(123123.3,'FM99,999,999.99') from dual; -----123,123.3 (前面去空格,后面不补0)
select to_char(123123.3,'$99,999,999.99') from dual; (加美元符号,可以联合使用 FM$)
select to_char(123123.3,'L99,999,999.99') from dual; (加本地货币符号 ¥)
select to_char(123123.3,'99,999,999.99C') from dual; (货币单位CNY)
第三节:日期类型及函数
Date 和 timestamp(时间戳)
Date 包含信息 century(世纪信息) year 年 month 月 day 日 hour 小时 minute 分钟 second 秒
Timestamp 一般用于日期时间要求非常精确的情况,精确到毫秒级;
insert into t_date values(1,sysdate,systimestamp);
下面重点讲 date 类型的常用函数:
select sysdate from dual;
select systimestamp from dual;
Add_months 添加月份 select add_months(d1,2) from t_date where id=1;
Last_day 返回指定日期月份的最后一天 select last_day(d1) from t_date where id=1;
update t_date set d3=to_date('2016-12-20','YYYY-MM-DD') where id=1;
update t_date set d3=to_date('2016-12-20 18:31:34','YYYY-MM-DD HH24:MI:SS') where id=1;
Months_between 返回两个日期的相差月数 select months_between(d1,d3) from t_date where id=1; (带小数的)
next_day 返回特定日期之后的一周内的日期:select next_day(d1,2) from t_date where id=1; (2代表周一)
Trunc 截取日期:
select trunc(d1,'YYYY') from t_date where id=1; 返回当年第一天,即截取到年,后面都是默认1月1日0点0分
select trunc(d1,'MM') from t_date where id=1; 返回当月第一天.即截取到月,后面都是默认1号0点0分
select trunc(d1,'DD') from t_date where id=1; 返回当前年月日
select trunc(d1,'HH') from t_date where id=1;
select trunc(d1,'MI') from t_date where id=1;
Extract 返回日期的某个域:
select extract(year from sysdate) from dual;
select extract(month from sysdate) from dual;
select extract(day from sysdate) from dual;
select extract(hour from systimestamp) from dual;
select extract(minute from systimestamp) from dual;
select extract(second from systimestamp) from dual;
//oracle中extract()函数从oracle 9i中引入,用于从一个date或者interval类型中截取到特定的部分 //语法如下: EXTRACT ( { YEAR | MONTH | DAY | HOUR | MINUTE | SECOND } | { TIMEZONE_HOUR | TIMEZONE_MINUTE } | { TIMEZONE_REGION | TIMEZONE_ABBR } FROM { date_value | interval_value } ) //我们只可以从一个date类型中截取 year,month,day(date日期的格式为yyyy-mm-dd); //我们只可以从一个 timestamp with time zone 的数据类型中截取TIMEZONE_HOUR和TIMEZONE_MINUTE; select extract(year from date'2011-05-17') year from dual; YEAR ---------- 2011 select extract(month from date'2011-05-17') month from dual; MONTH ---------- 5 select extract(day from date'2011-05-17') day from dual; DAY ---------- 17 //获取两个日期之间的具体时间间隔,extract函数是最好的选择 select extract(day from dt2-dt1) day ,extract(hour from dt2-dt1) hour ,extract(minute from dt2-dt1) minute ,extract(second from dt2-dt1) second from ( select to_timestamp('2011-02-04 15:07:00','yyyy-mm-dd hh24:mi:ss') dt1 ,to_timestamp('2011-05-17 19:08:46','yyyy-mm-dd hh24:mi:ss') dt2 from dual) / DAY HOUR MINUTE SECOND ---------- ---------- ---------- ---------- 102 4 1 46 -- select extract(year from systimestamp) year ,extract(month from systimestamp) month ,extract(day from systimestamp) day ,extract(minute from systimestamp) minute ,extract(second from systimestamp) second ,extract(timezone_hour from systimestamp) th ,extract(timezone_minute from systimestamp) tm ,extract(timezone_region from systimestamp) tr ,extract(timezone_abbr from systimestamp) ta from dual / YEAR MONTH DAY MINUTE SECOND TH TM TR TA ---------- ---------- ---------- ---------- ---------- ---------- ---------- --------- ---------- 2011 5 17 7 14.843 8 0 UNKNOWN UNK //
To_char 将日期转换成字符串:
select to_char(d1,'YYYY-MM-DD') from t_date where id=1;
select to_char(d1,'YYYY-MM-DD HH24:MI:SS') from t_date where id=1;
Oracle中TO_DATE格式2009-04-14 10:53TO_DATE格式(以时间:2007-11-02 13:45:25为例) Year: yy two digits 两位年 显示值:07 yyy three digits 三位年 显示值:007 yyyy four digits 四位年 显示值:2007 Month: mm number 两位月 显示值:11 mon abbreviated 字符集表示 显示值:11月,若是英文版,显示nov month spelled out 字符集表示 显示值:11月,若是英文版,显示november Day: dd number 当月第几天 显示值:02 ddd number 当年第几天 显示值:02 dy abbreviated 当周第几天简写 显示值:星期五,若是英文版,显示fri day spelled out 当周第几天全写 显示值:星期五,若是英文版,显示friday ddspth spelled out, ordinal twelfth Hour: hh two digits 12小时进制 显示值:01 hh24 two digits 24小时进制 显示值:13 Minute: mi two digits 60进制 显示值:45 Second: ss two digits 60进制 显示值:25 其它 Q digit 季度 显示值:4 WW digit 当年第几周 显示值:44 W digit 当月第几周 显示值:1 24小时格式下时间范围为: 0:00:00 - 23:59:59.... 12小时格式下时间范围为: 1:00:00 - 12:59:59 .... 1. 日期和字符转换函数用法(to_date,to_char) select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') as nowTime from dual; //日期转化为字符串 select to_char(sysdate,'yyyy') as nowYear from dual; //获取时间的年 select to_char(sysdate,'mm') as nowMonth from dual; //获取时间的月 select to_char(sysdate,'dd') as nowDay from dual; //获取时间的日 select to_char(sysdate,'hh24') as nowHour from dual; //获取时间的时 select to_char(sysdate,'mi') as nowMinute from dual; //获取时间的分 select to_char(sysdate,'ss') as nowSecond from dual; //获取时间的秒 select to_date('2004-05-07 13:23:44','yyyy-mm-dd hh24:mi:ss') from dual// 2. select to_char( to_date(222,'J'),'Jsp') from dual 显示Two Hundred Twenty-Two 3.求某天是星期几 select to_char(to_date('2002-08-26','yyyy-mm-dd'),'day') from dual; 星期一 select to_char(to_date('2002-08-26','yyyy-mm-dd'),'day','NLS_DATE_LANGUAGE = American') from dual; monday 设置日期语言 ALTER SESSION SET NLS_DATE_LANGUAGE='AMERICAN'; 也可以这样 TO_DATE ('2002-08-26', 'YYYY-mm-dd', 'NLS_DATE_LANGUAGE = American') 4. 两个日期间的天数 select floor(sysdate - to_date('20020405','yyyymmdd')) from dual; 5. 时间为null的用法 select id, active_date from table1 UNION select 1, TO_DATE(null) from dual; 注意要用TO_DATE(null) 6.月份差 a_date between to_date('20011201','yyyymmdd') and to_date('20011231','yyyymmdd') 那么12月31号中午12点之后和12月1号的12点之前是不包含在这个范围之内的。 所以,当时间需要精确的时候,觉得to_char还是必要的 7. 日期格式冲突问题 输入的格式要看你安装的ORACLE字符集的类型, 比如: US7ASCII, date格式的类型就是: '01-Jan-01' alter system set NLS_DATE_LANGUAGE = American alter session set NLS_DATE_LANGUAGE = American 或者在to_date中写 select to_char(to_date('2002-08-26','yyyy-mm-dd'),'day','NLS_DATE_LANGUAGE = American') from dual; 注意我这只是举了NLS_DATE_LANGUAGE,当然还有很多, 可查看 select * from nls_session_parameters select * from V$NLS_PARAMETERS 8. select count(*) from ( select rownum-1 rnum from all_objects where rownum <= to_date('2002-02-28','yyyy-mm-dd') - to_date('2002- 02-01','yyyy-mm-dd')+1 ) where to_char( to_date('2002-02-01','yyyy-mm-dd')+rnum-1, 'D' ) not in ( '1', '7' ) 查找2002-02-28至2002-02-01间除星期一和七的天数 在前后分别调用DBMS_UTILITY.GET_TIME, 让后将结果相减(得到的是1/100秒, 而不是毫秒). 9. 查找月份 select months_between(to_date('01-31-1999','MM-DD-YYYY'),to_date('12-31-1998','MM-DD-YYYY')) "MONTHS" FROM DUAL; 1 select months_between(to_date('02-01-1999','MM-DD-YYYY'),to_date('12-31-1998','MM-DD-YYYY')) "MONTHS" FROM DUAL; 1.03225806451613 10. Next_day的用法 Next_day(date, day) Monday-Sunday, for format code DAY Mon-Sun, for format code DY 1-7, for format code D 11 select to_char(sysdate,'hh:mi:ss') TIME from all_objects 注意:第一条记录的TIME 与最后一行是一样的 可以建立一个函数来处理这个问题 create or replace function sys_date return date is begin return sysdate; end; select to_char(sys_date,'hh:mi:ss') from all_objects; 12.获得小时数 extract()找出日期或间隔值的字段值 SELECT EXTRACT(HOUR FROM TIMESTAMP '2001-02-16 2:38:40') from offer SQL> select sysdate ,to_char(sysdate,'hh') from dual; SYSDATE TO_CHAR(SYSDATE,'HH') -------------------- --------------------- 2003-10-13 19:35:21 07 SQL> select sysdate ,to_char(sysdate,'hh24') from dual; SYSDATE TO_CHAR(SYSDATE,'HH24') -------------------- ----------------------- 2003-10-13 19:35:21 19 13.年月日的处理 select older_date, newer_date, years, months, abs( trunc( newer_date- add_months( older_date,years*12+months ) ) ) days from ( select trunc(months_between( newer_date, older_date )/12) YEARS, mod(trunc(months_between( newer_date, older_date )),12 ) MONTHS, newer_date, older_date from ( select hiredate older_date, add_months(hiredate,rownum)+rownum newer_date from emp ) ) 14.处理月份天数不定的办法 select to_char(add_months(last_day(sysdate) +1, -2), 'yyyymmdd'),last_day(sysdate) from dual 16.找出今年的天数 select add_months(trunc(sysdate,'year'), 12) - trunc(sysdate,'year') from dual 闰年的处理方法 to_char( last_day( to_date('02' | | :year,'mmyyyy') ), 'dd' ) 如果是28就不是闰年 17.yyyy与rrrr的区别 'YYYY99 TO_C ------- ---- yyyy 99 0099 rrrr 99 1999 yyyy 01 0001 rrrr 01 2001 18.不同时区的处理 select to_char( NEW_TIME( sysdate, 'GMT','EST'), 'dd/mm/yyyy hh:mi:ss') ,sysdate from dual; 19.5秒钟一个间隔 Select TO_DATE(FLOOR(TO_CHAR(sysdate,'SSSSS')/300) * 300,'SSSSS') ,TO_CHAR(sysdate,'SSSSS') from dual 2002-11-1 9:55:00 35786 SSSSS表示5位秒数 20.一年的第几天 select TO_CHAR(SYSDATE,'DDD'),sysdate from dual 310 2002-11-6 10:03:51 21.计算小时,分,秒,毫秒 select Days, A, TRUNC(A*24) Hours, TRUNC(A*24*60 - 60*TRUNC(A*24)) Minutes, TRUNC(A*24*60*60 - 60*TRUNC(A*24*60)) Seconds, TRUNC(A*24*60*60*100 - 100*TRUNC(A*24*60*60)) mSeconds from ( select trunc(sysdate) Days, sysdate - trunc(sysdate) A from dual ) select * from tabname order by decode(mode,'FIFO',1,-1)*to_char(rq,'yyyymmddhh24miss'); // floor((date2-date1) /365) 作为年 floor((date2-date1, 365) /30) 作为月 d(mod(date2-date1, 365), 30)作为日. 23.next_day函数 返回下个星期的日期,day为1-7或星期日-星期六,1表示星期日 next_day(sysdate,6)是从当前开始下一个星期五。后面的数字是从星期日开始算起。 1 2 3 4 5 6 7 日 一 二 三 四 五 六 --------------------------------------------------------------- select (sysdate-to_date('2003-12-03 12:55:45','yyyy-mm-dd hh24:mi:ss'))*24*60*60 from ddual 日期 返回的是天 然后 转换为ss 24,round[舍入到最接近的日期](day:舍入到最接近的星期日) select sysdate S1, round(sysdate) S2 , round(sysdate,'year') YEAR, round(sysdate,'month') MONTH , round(sysdate,'day') DAY from dual 25,trunc[截断到最接近的日期,单位为天] ,返回的是日期类型 select sysdate S1, trunc(sysdate) S2, //返回当前日期,无时分秒 trunc(sysdate,'year') YEAR, //返回当前年的1月1日,无时分秒 trunc(sysdate,'month') MONTH , //返回当前月的1日,无时分秒 trunc(sysdate,'day') DAY //返回当前星期的星期天,无时分秒 from dual 26,返回日期列表中最晚日期 select greatest('01-1月-04','04-1月-04','10-2月-04') from dual 27.计算时间差 注:oracle时间差是以天数为单位,所以换算成年月,日 select floor(to_number(sysdate-to_date('2007-11-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))/365) as spanYears from dual //时间差-年 select ceil(moths_between(sysdate-to_date('2007-11-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))) as spanMonths from dual //时间差-月 select floor(to_number(sysdate-to_date('2007-11-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))) as spanDays from dual //时间差-天 select floor(to_number(sysdate-to_date('2007-11-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))*24) as spanHours from dual //时间差-时 select floor(to_number(sysdate-to_date('2007-11-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))*24*60) as spanMinutes from dual //时间差-分 select floor(to_number(sysdate-to_date('2007-11-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))*24*60*60) as spanSeconds from dual //时间差-秒 28.更新时间 注:oracle时间加减是以天数为单位,设改变量为n,所以换算成年月,日 select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'),to_char(sysdate+n*365,'yyyy-mm-dd hh24:mi:ss') as newTime from dual //改变时间-年 select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'),add_months(sysdate,n) as newTime from dual //改变时间-月 select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'),to_char(sysdate+n,'yyyy-mm-dd hh24:mi:ss') as newTime from dual //改变时间-日 select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'),to_char(sysdate+n/24,'yyyy-mm-dd hh24:mi:ss') as newTime from dual //改变时间-时 select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'),to_char(sysdate+n/24/60,'yyyy-mm-dd hh24:mi:ss') as newTime from dual //改变时间-分 select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'),to_char(sysdate+n/24/60/60,'yyyy-mm-dd hh24:mi:ss') as newTime from dual //改变时间-秒 29.查找月的第一天,最后一天 SELECT Trunc(Trunc(SYSDATE, 'MONTH') - 1, 'MONTH') First_Day_Last_Month, Trunc(SYSDATE, 'MONTH') - 1 / 86400 Last_Day_Last_Month, Trunc(SYSDATE, 'MONTH') First_Day_Cur_Month, LAST_DAY(Trunc(SYSDATE, 'MONTH')) + 1 - 1 / 86400 Last_Day_Cur_Month FROM dual;
第四节:其他常用处理函数
常用的聚合函数:
Max 求最大值:select max(sal) from emp ;
Min 求最小值:select min(sal) from emp ;
Avg 求平均值:select avg(sal) from emp ;
Sum 求和:select sum(sal) from emp ;
Count 统计记录数:select count(ename) from emp ;
Nvl 空值处理:select ename,nvl(sal,0) from emp;
rownum
Oracle 分页:select * from (select a.*,rownum rn from (select * from emp) A where rownum<=10) where rn>5;
Oracle 中的运算:
select 2+1 from dual;
select 2-1 from dual;
select 2*1 from dual;
select 2/1 from dual;
条件判断式:
Between and 范围查询:
select * from emp where sal between 900 and 1500;
select * from emp where sal>=900 and sal<=1500;
In 集合范围:
select ename,hiredate from emp where ename in (select distinct ename from bonus)
Like 模糊查询:
select * from emp where ename like '%M%'
select * from emp where ename like 'M%'
select * from emp where ename like '_M%'

浙公网安备 33010602011771号