2017.10.26 - BoobooWei
前面SQL语句 01~05 我们学习了查询语句的基础用法,今天在补充以下知识点:
- 集合运算
- 扩展的时间
- 日期函数
- 增强的Group By
- 高级子查询
- insert扩展
- 外部表
- exists
集合运算
union会压缩重复值
select * from e01 |
union all没有去重效果
select * from e01 |
intersect求交集
select * from e01 |
minus求集合A与集合B不同的地方
select * from e01 |
练习select * from e01
union all
select dept.*,null,null,null,null,null from dept;
SQL> select * from e01 union all select dept.*,null,null,null,null,null from dept;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- -------------- ------------- ---------- --------- ---------- ---------- ----------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
扩展的时间
时间戳timestamp
SQL> create table t01 (x int,y timestamp); |
练习
SQL> select * from tab; |
全球化时间戳timestamp with time zone
create table t02 (x int,y timestamp with time zone); |
练习
SQL> create table t02 (id int,hiredate timestamp with time zone); |
本地时间戳timestamp with local time zone
SQL> create table t03 (x int,y timestamp with local time zone); |
练习SQL> create table t03 (id int,hiredate timestamp with local time zone);
Table created.
SQL> insert into t03 values (1,current_date);
1 row created.
SQL> select * from t03;
ID HIREDATE
---------- ---------------------------------------------------------------------------
1 26-OCT-17 07.55.00.000000 PM
当前会话的时区sessiontimezone
SQL> select sessiontimezone from dual; |
实践1-练习修改时区
SQL> alter session set time_zone='-08:00'; |
当前数据库时区
SQL> select dbtimezone from dual; |
时间函数
- sysdate 返回操作系统时间一样
- current_date 受当前会话时区影响
- current_timestamp 不受时区影响
- localtimestamp 受当前会话时区影响
- extract()萃取函数
- from_tz()函数实现与时间戳的转换
- tz_offset()函数将时区别名转换为以UTC为标准的OFFSET
- to_timestamp() 转化为时间戳
- to_timestamp_tz() 返回带时区的时间戳
- to_yminterval() 返回时间段(年月)
- to_dsinterval() 返回时间段(天小时分钟秒)
练习SQL> select sysdate,current_date,current_timestamp,localtimestamp from dual;
SYSDATE CURRENT_D CURRENT_TIMESTAMP LOCALTIMESTAMP
--------- --------- --------------------------------------------------------------------------- ---------------------------------------------------------------------------
26-OCT-17 26-OCT-17 26-OCT-17 08.13.25.606912 PM +08:00 26-OCT-17 08.13.25.606912 PM
SQL> alter session set time_zone='+5:00';
Session altered.
SQL> select sysdate,current_date,current_timestamp,localtimestamp from dual;
SYSDATE CURRENT_D CURRENT_TIMESTAMP LOCALTIMESTAMP
--------- --------- --------------------------------------------------------------------------- ---------------------------------------------------------------------------
26-OCT-17 26-OCT-17 26-OCT-17 05.14.45.191839 PM +05:00 26-OCT-17 05.14.45.191839 PM
实践1
SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'),to_char(current_date,'yyyy-mm-dd hh24:mi:ss') from dual; |
实践2
SQL> select extract(month from sysdate) from dual; |
实践3
SQL> select from_tz(timestamp '2015-12-22 13:58:00','+08:00') from dual; |
增强的Group By
roll()
n+1种聚集运算的结果
roll(a,b,c) --> n+1种聚集运算的结果 |
cube()
2的n次方种聚集运算的结果
cube(a,b,c) --> 2的n次方种聚集运算的结果 |
实践
select deptno,job,sum(sal),grouping(deptno),grouping(job) |
练习结果
--mysql中对应的方法为 group by deptno, job with rollup |
高级子查询
with as ()
哪些部门的总工资高于所有部门的平均总工资
with |
分级查询(爬树)
select level,lpad(ename,length(ename)+level*2-2,' ') ename |
修改爬树的起点: start with
select level,lpad(ename,length(ename)+level*2-2,' ') ename |
修改爬树的方向:connect by prior 父键在前向下爬,子键在前向上爬
select level,lpad(ename,length(ename)+level*2-2,' ') ename |
剪枝:
剪枝条件出现在where子句,剪一个节点
select level,lpad(ename,length(ename)+level*2-2,' ') ename |
剪枝条件出现在connect by prior子句,剪一个派系
select level,lpad(ename,length(ename)+level*2-2,' ') ename |
insert扩展
insert all
drop table e01 purge; |
带条件的insert all
insert all |
带条件的insert first
insert first |
旋转插入
创建一张表:销售元数据
create table sales_source_data (employee_id number,week_id number,sales_mon number,sales_tue number,sales_wed number,sales_thur number,sales_fri number); |
创建一张表:销售信息表
create table sales_info (employee_id number,week number,sales number); |
insert all |
create table sales_info (employee_id number,week_id number,day_id varchar2(4),sales number); |
外部表
准备文本文件
vi /home/oracle/1.txt |
创建逻辑目录并授权
conn / as sysdba |
创建外部表
conn scott/tiger |
exists
select * from e01 a where exists (select 1 from e01 where a.rowid!=e01.rowid and e01.empno=a.empno); |
找到重复的行
select * from e01 a where exists (select 1 from e01 e where a.rowid!=e.rowid and e.empno=a.empno); |
查找重复行的rowid 方法1:select rowid from e01 a where a.rowid!= (select max(rowid) from e01 e where e.empno=a.empno and e.ename=a.ename);
查找重复行的rowid 方法2:select rowid from e01 a where rowid not in (select max(rowid) from e01 group by empno,ename);
找到不重复的行select * from e01 a where not exists (select 1 from e01 e where a.rowid!=e.rowid and e.empno=a.empno);
去掉重复的行:select * from e01 a where rowid in (select max(rowid) from e01 e where e.empno=a.empno);